<?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: vimuth</title>
    <description>The latest articles on DEV Community by vimuth (@vimuth7).</description>
    <link>https://dev.to/vimuth7</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%2F197191%2Ff110a3e8-f76c-40a5-8b2e-aae9dbf8b6ff.JPEG</url>
      <title>DEV Community: vimuth</title>
      <link>https://dev.to/vimuth7</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vimuth7"/>
    <language>en</language>
    <item>
      <title>How to Implement Stripe Payments with Payment Intents and Webhooks for Complete Payment Flow Management</title>
      <dc:creator>vimuth</dc:creator>
      <pubDate>Thu, 03 Apr 2025 13:11:45 +0000</pubDate>
      <link>https://dev.to/vimuth7/how-to-implement-stripe-payments-with-payment-intents-and-webhooks-for-complete-payment-flow-1klf</link>
      <guid>https://dev.to/vimuth7/how-to-implement-stripe-payments-with-payment-intents-and-webhooks-for-complete-payment-flow-1klf</guid>
      <description>&lt;p&gt;In today’s digital economy, integrating a reliable payment gateway is crucial for any online business. Stripe, one of the most popular payment processing platforms, offers a powerful solution for handling payments securely and efficiently. In this tutorial, we'll walk you through how to implement Stripe Payments using Payment Intents and Webhooks.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Starting the Project:
&lt;/h2&gt;

&lt;p&gt;To kick things off, we’ll begin by setting up a basic Node.js project. I’ve already created the project and initialized it in Git, so we won’t need to go through the setup steps from scratch. Let’s jump straight into the implementation of Stripe payment integration.&lt;/p&gt;

&lt;p&gt;"&lt;a href="https://github.com/vimuths123/stripeapp.git" rel="noopener noreferrer"&gt;https://github.com/vimuths123/stripeapp.git&lt;/a&gt;" this repos has a branch called &lt;strong&gt;initial_project&lt;/strong&gt;. This has a simple node project with this structure&lt;/p&gt;

&lt;p&gt;stripe-payment/&lt;br&gt;
│── public/&lt;br&gt;
│   └── index.html  (Frontend)&lt;br&gt;
│── .env            (Environment variables)&lt;br&gt;
│── package.json    (Project metadata)&lt;br&gt;
│── server.js       (Backend server)&lt;/p&gt;

&lt;p&gt;And it has installed all packages needed like &lt;strong&gt;"body-parser", "cors", "dotenv", "express", "stripe", "nodemon"&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Implementing Stripe Payment Intents
&lt;/h2&gt;

&lt;p&gt;In this section, we will create a &lt;strong&gt;Payment Intent&lt;/strong&gt; on the server-side to handle the payment process securely. The &lt;strong&gt;Payment Intent&lt;/strong&gt; represents your intent to collect a payment and manages the complexities of authentication and authorization, like 3D Secure.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Set up the Environment
&lt;/h3&gt;

&lt;p&gt;Before we create the Payment Intent, make sure you have added your Stripe API keys in the .env file. You can find your keys in the &lt;a href="https://dashboard.stripe.com/test/apikeys" rel="noopener noreferrer"&gt;Stripe Dashboard&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the .env file, add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;STRIPE_SECRET_KEY=your_stripe_secret_key
STRIPE_PUBLISHABLE_KEY=your_stripe_publishable_key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Create the Payment Intent Route
&lt;/h3&gt;

&lt;p&gt;In your server.js file, we’ll create an endpoint that will handle creating the Payment Intent. &lt;strong&gt;When a client sends a payment request, this endpoint will interact with Stripe to create a Payment Intent and return the client secret to the frontend&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Open the server.js file and add the following code to create the Payment Intent:&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 bodyParser = require("body-parser");
const cors = require("cors");
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);

const app = express();

// Middleware
app.use(cors());
app.use(bodyParser.json());

// Create Payment Intent endpoint
app.post("/create-payment-intent", async (req, res) =&amp;gt; {
  try {
    const { amount, currency } = req.body;

    // Create Payment Intent
    const paymentIntent = await stripe.paymentIntents.create({
      amount: amount * 100, // Convert to cents
      currency: currency,
    });

    // Send the client secret to the client
    res.send({
      clientSecret: paymentIntent.client_secret,
    });
  } catch (error) {
    res.status(500).send({
      error: error.message,
    });
  }
});

// Start the server
const port = process.env.PORT || 5000;
app.listen(port, () =&amp;gt; {
  console.log(`Server running on port ${port}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you can see we take stripe secret from .env and create stripe object to get the payment intent&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const paymentIntent = await stripe.paymentIntents.create({
      amount: amount * 100, // Convert to cents
      currency: currency,
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can test the server by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can se the code until this with &lt;strong&gt;"backend_payment_intent"&lt;/strong&gt; branch or previous repo.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Frontend Implementation: Handling Stripe Payment
&lt;/h2&gt;

&lt;p&gt;In this section, we will build the frontend to collect payment information from the user and complete the payment using Stripe's Payment Intent.&lt;/p&gt;

&lt;p&gt;I have added a page called public/index.html in root. But to populate this we need to do a small change in server.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const path = require('path');

// Serve static files from the 'public' folder
app.use(express.static(path.join(__dirname, 'public')));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line of code is used to serve static files (such as HTML, CSS, JavaScript, images, etc.) from a specific folder, in this case, the public folder.&lt;/p&gt;

&lt;p&gt;Now if we run '&lt;a href="http://localhost:5000/" rel="noopener noreferrer"&gt;http://localhost:5000/&lt;/a&gt;' this index.html file will be shown in browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Add Stripe.js to Your HTML
&lt;/h3&gt;

&lt;p&gt;First, we need to include Stripe.js in the &lt;/p&gt; section of your index.html file. This script will provide the necessary functions to interact with Stripe on the client side. You can see this index.html in git repo.&lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script src="https://js.stripe.com/v3/"&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  2. Get the payment intent and confirm payment
&lt;/h3&gt;

&lt;p&gt;Upon clicking the button, we make a request to the previously created endpoint, passing the payment amount and currency. The server responds with the payment intent ID, which includes the Stripe secret.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let response = await fetch("http://localhost:5000/create-payment-intent", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ amount: amount, currency: "usd" }),
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These lines retrieve the payment intent's client secret from the server response and then use it to confirm the payment with Stripe.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let { clientSecret } = await response.json();

let { paymentIntent, error } = await stripe.confirmCardPayment(clientSecret, {
    payment_method: { card: cardElement },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Flow:&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;1. Backend creates a PaymentIntent:&lt;/strong&gt; The server creates a PaymentIntent and returns a clientSecret.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Frontend confirms the payment:&lt;/strong&gt; The frontend uses the clientSecret to confirm the payment by calling stripe.confirmCardPayment() with the user's card details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Success or error:&lt;/strong&gt; If the payment is successful, the paymentIntent is returned, which contains the payment details. If the payment fails, the error is returned, and you can handle it accordingly (e.g., showing an error message).&lt;/p&gt;

&lt;p&gt;You can find changes upto this point with &lt;strong&gt;frontend_implementation&lt;/strong&gt; git branch.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Save the data with stripe webhook.
&lt;/h2&gt;

&lt;p&gt;Now we may need to save data to the db or add a record that payment happened. Now we can do it by sending ajax call from front end. But that have issues.&lt;/p&gt;

&lt;p&gt;Users can change the payment amount and send or user may close the window before the axios call and also another axios call may slow the user experience. So best way is letting stripe call the webhook url.&lt;/p&gt;

&lt;p&gt;let's add one more endpoint to server.js&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("/webhook", express.raw({ type: "application/json" })); // Webhook requires raw body


app.post("/webhook", express.raw({ type: "application/json" }), (req, res) =&amp;gt; {
    const sig = req.headers["stripe-signature"];

    let event;
    try {
        // Use req.body directly (raw Buffer) for signature verification
        event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_WEBHOOK_SECRET);
    } catch (err) {
        console.error("Webhook signature verification failed:", err.message);
        return res.status(400).send(`Webhook Error: ${err.message}`);
    }

    console.log("Webhook received:", event.type);

    res.json({ received: true });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have two ways of adding stripe webhook. If we have a server then we can get this endpoint and add it here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dashboard.stripe.com/test/webhooks" rel="noopener noreferrer"&gt;https://dashboard.stripe.com/test/webhooks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that we can get 'STRIPE_WEBHOOK_SECRET' and add it to .env. But if you are using localhost you need to add Stripe CLI and run webhook from here.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Run with Stripe CLI
&lt;/h2&gt;

&lt;p&gt;First you need to install the stripe CLI. Since I use windows I get it from here&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.stripe.com/stripe-cli?install-method=windows" rel="noopener noreferrer"&gt;https://docs.stripe.com/stripe-cli?install-method=windows&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;You just have to copy the extracted data to a folder and give environment variable&lt;/p&gt;

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

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

&lt;p&gt;Then run this&lt;/p&gt;

&lt;p&gt;stripe listen --forward-to &lt;a href="http://localhost:5000/webhook" rel="noopener noreferrer"&gt;http://localhost:5000/webhook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is it. Happy coding.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>stripe</category>
      <category>programming</category>
    </item>
    <item>
      <title>Automate Laravel Deployment on Hostinger with GitHub Actions: A Step-by-Step Guide</title>
      <dc:creator>vimuth</dc:creator>
      <pubDate>Sun, 26 Jan 2025 10:36:09 +0000</pubDate>
      <link>https://dev.to/vimuth7/automate-laravel-deployment-on-hostinger-with-github-actions-a-step-by-step-guide-58k1</link>
      <guid>https://dev.to/vimuth7/automate-laravel-deployment-on-hostinger-with-github-actions-a-step-by-step-guide-58k1</guid>
      <description>&lt;p&gt;Previously I added a blog on deploying a laravel application on Hostinger. This is an extension on this.&lt;/p&gt;

&lt;p&gt;This is the previous article. - &lt;a href="https://dev.to/vimuth7/deploy-a-laravel-app-on-hostinger-using-git-1ice"&gt;Effortless Laravel Deployment on Hostinger Using Git: A Step-by-Step Guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub Actions is a powerful automation tool that allows you to streamline your development workflow. When you push a change to a GitHub repository branch, GitHub can automatically trigger a workflow to deploy that branch to your server. This seamless process ensures continuous integration and deployment without manual intervention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Deployment Script for GitHub Actions
&lt;/h2&gt;

&lt;p&gt;Let's create a &lt;strong&gt;deploy.sh&lt;/strong&gt; file and add all the necessary laravel related commands here.&lt;/p&gt;

&lt;p&gt;First login via SSH and go to your site location&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /home/youruser/domains/yourdomain.hostingersite.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create deploy.sh file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano deploy.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this to file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

# Define a function to check the status of the last executed command
check_status() {
    if [ $? -eq 0 ]; then
        echo "✅ $1 succeeded."
    else
        echo "❌ $1 failed."
        exit 1
    fi
}

composer2 install --no-interaction
check_status "Composer Install"

npm install
check_status "NPM Install"

npm run build
check_status "NPM Run Build"

# Run migrations
php artisan migrate --force
check_status "PHP Artisan Migrate"

# Run database seeders
php artisan db:seed --force
check_status "PHP Artisan DB Seed"

# Clear caches
php artisan config:clear
check_status "PHP Artisan Config Clear"

php artisan cache:clear
check_status "PHP Artisan Cache Clear"

php artisan view:clear
check_status "PHP Artisan View Clear"

php artisan route:clear
check_status "PHP Artisan Route Clear"

# Rebuild caches
php artisan config:cache
check_status "PHP Artisan Config Cache"

php artisan route:cache
check_status "PHP Artisan Route Cache"

php artisan view:cache
check_status "PHP Artisan View Cache"

echo "✅ Deployment complete."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see all the Laravel commands here. &lt;/p&gt;

&lt;h2&gt;
  
  
  Create the &lt;strong&gt;GitHub Actions workflow&lt;/strong&gt; file
&lt;/h2&gt;

&lt;p&gt;Let's create a GitHub Actions workflow file that automates the deployment of your project to a Hostinger server whenever changes are pushed to a particular branch&lt;/p&gt;

&lt;p&gt;Add this file to you github repo &lt;strong&gt;.github\workflows\maindeploy.yml&lt;/strong&gt;. And add this content&lt;/p&gt;

&lt;p&gt;name: Deploy to Hostinger Server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout repository
      uses: actions/checkout@v3

    - name: Install sshpass (if using password authentication)
      run: sudo apt-get install -y sshpass

    - name: Deploy to Hostinger via SSH with custom port
      env:
        HOSTINGER_IP: ${{ secrets.HOSTINGER_IP }}
        HOSTINGER_PORT: ${{ secrets.HOSTINGER_PORT }}
        HOSTINGER_USERNAME: ${{ secrets.HOSTINGER_USERNAME }}
        HOSTINGER_PASSWORD: ${{ secrets.HOSTINGER_PASSWORD }}
      run: |
        # Specify custom port with -P for scp
        sshpass -p "$HOSTINGER_PASSWORD" scp -P $HOSTINGER_PORT -o StrictHostKeyChecking=no -r * $HOSTINGER_USERNAME@$HOSTINGER_IP:/home/youruser/domains/yourdomain.hostingersite.com

        # Specify custom port with -p for ssh
        sshpass -p "$HOSTINGER_PASSWORD" ssh -p $HOSTINGER_PORT -o StrictHostKeyChecking=no $HOSTINGER_USERNAME@$HOSTINGER_IP "cd /home/youruser/domains/yourdomain.hostingersite.com &amp;amp;&amp;amp; bash deploy.sh"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see &lt;strong&gt;"/home/youruser/domains/yourdomain.hostingersite.com"&lt;/strong&gt; in two places. You must change this to your actual location. More about this you can find in first video.&lt;/p&gt;

&lt;p&gt;And remember that here you are using default &lt;strong&gt;main&lt;/strong&gt; branch. if you need change the branch here&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;on:
  push:
    branches:
      - main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add repository secret values
&lt;/h2&gt;

&lt;p&gt;You can see this section&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;env:
        HOSTINGER_IP: ${{ secrets.HOSTINGER_IP }}
        HOSTINGER_PORT: ${{ secrets.HOSTINGER_PORT }}
        HOSTINGER_USERNAME: ${{ secrets.HOSTINGER_USERNAME }}
        HOSTINGER_PASSWORD: ${{ secrets.HOSTINGER_PASSWORD }}

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

&lt;/div&gt;



&lt;p&gt;You must add these values as github repository secrets. Let me show how. First go to repository and got to &lt;strong&gt;Settings -&amp;gt; Secrets and variables -&amp;gt; Actions&lt;/strong&gt; and you can add these values.&lt;/p&gt;

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

&lt;p&gt;That's it and when you see the actions tab you can see the action status.&lt;/p&gt;

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

&lt;p&gt;Thanks and that's all you have to do.&lt;/p&gt;

</description>
      <category>githubactions</category>
      <category>laravel</category>
      <category>hostinger</category>
    </item>
    <item>
      <title>Building a Simple Laravel App with Reverb: A Step-by-Step Guide</title>
      <dc:creator>vimuth</dc:creator>
      <pubDate>Sat, 25 Jan 2025 08:51:20 +0000</pubDate>
      <link>https://dev.to/vimuth7/building-a-simple-laravel-app-with-reverb-a-step-by-step-guide-19g5</link>
      <guid>https://dev.to/vimuth7/building-a-simple-laravel-app-with-reverb-a-step-by-step-guide-19g5</guid>
      <description>&lt;p&gt;Laravel is a powerful PHP framework known for its elegant syntax and developer-friendly features. Reverb, Laravel’s real-time event broadcasting system, makes it easy to integrate live updates into your applications. In this guide, we’ll walk through building a simple Laravel app with Reverb, showing how to set up real-time functionality step by step. Whether you're new to Laravel or looking to explore real-time features, this tutorial will help you get started quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install laravel
&lt;/h2&gt;

&lt;p&gt;First let's install laravel.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;composer create-project --prefer-dist laravel/laravel reverbapp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And inside &lt;strong&gt;reverbapp&lt;/strong&gt; folder add &lt;code&gt;php artisan serve&lt;/code&gt; and test the app.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Install Reverb
&lt;/h2&gt;

&lt;p&gt;Let's install reverb. Give yes to all prompts appear. They will install reverb PHP packages and Node packages like echo and pusher-js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan install:broadcasting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can see inside .env these settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BROADCAST_CONNECTION=reverb
REVERB_APP_ID=981064
REVERB_APP_KEY=oi4rnynjhmgd5vvz024v
REVERB_APP_SECRET=uxtmtcqs30kh2vcqpt58
REVERB_HOST="localhost"
REVERB_PORT=8080
REVERB_SCHEME=http

VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Building the App
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Lets create the event
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan make:event MessageSent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll modify this event to broadcast a simple &lt;strong&gt;$messag&lt;/strong&gt;e object via 'public-messages' public channel. Here is the code&lt;br&gt;
&lt;/p&gt;

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

namespace App\Events;

use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\Channel; // Public Channel
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class MessageSent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $message;

    public function __construct($message)
    {
        $this-&amp;gt;message = $message;
    }

    // Broadcast via public channel
    public function broadcastOn()
    {
        return new Channel('public-messages');
    }

    public function broadcastAs()
    {
        return 'message.sent';
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Let's create two routes and a view in Laravel:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;One route to send data&lt;/li&gt;
&lt;li&gt;One route with a view to receive data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is send route&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Illuminate\Support\Facades\Route;
use App\Events\MessageSent;

Route::get('/send-message', function () {
    // Sending a simple object instead of a model
    $message = [
        'user' =&amp;gt; 'John Doe',
        'text' =&amp;gt; 'Hello from Laravel Reverb!',
        'timestamp' =&amp;gt; now()-&amp;gt;toDateTimeString(),
    ];

    // Fire the event
    broadcast(new MessageSent($message));

    return response()-&amp;gt;json(['status' =&amp;gt; 'Message broadcasted!']);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is revive route.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Route::get('/receive-data', function () {
    return view('receive');
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And view&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
    &amp;lt;title&amp;gt;Reverb Broadcast&amp;lt;/title&amp;gt;
    @vite(['resources/js/app.js']) {{-- Load JS --}}
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Listening for Messages...&amp;lt;/h1&amp;gt;
    &amp;lt;pre id="output"&amp;gt;&amp;lt;/pre&amp;gt;

    &amp;lt;script&amp;gt;
        document.addEventListener("DOMContentLoaded", function () {
            window.Echo.channel("public-messages")
                .listen(".message.sent", (event) =&amp;gt; {
                    console.log("Received:", event);
                    document.getElementById("output").textContent = JSON.stringify(event, null, 2);
                });
        });
    &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you need to run &lt;code&gt;npm run dev&lt;/code&gt; or &lt;code&gt;npm run build&lt;/code&gt; to allow &lt;strong&gt;window.Echo&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Combining with reverb
&lt;/h2&gt;

&lt;p&gt;First let's start reverb server. Run this command in different cli&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan reverb:start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can see websocket connection is made&lt;/p&gt;

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

&lt;p&gt;But you need to open a new window and also the run this command for processing jobs that are queued for execution in the background.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan queue:work
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is it. When you insert '&lt;a href="http://localhost:8000/send-message" rel="noopener noreferrer"&gt;http://localhost:8000/send-message&lt;/a&gt;' in window you will see this in another window&lt;/p&gt;

&lt;p&gt;And receive it from '&lt;a href="http://localhost:8000/receive-data" rel="noopener noreferrer"&gt;http://localhost:8000/receive-data&lt;/a&gt;'&lt;/p&gt;

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

&lt;p&gt;Let's meet with another post about how to deploy this to server.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Effortless Laravel Deployment on Hostinger Using Git: A Step-by-Step Guide</title>
      <dc:creator>vimuth</dc:creator>
      <pubDate>Fri, 24 Jan 2025 07:59:43 +0000</pubDate>
      <link>https://dev.to/vimuth7/deploy-a-laravel-app-on-hostinger-using-git-1ice</link>
      <guid>https://dev.to/vimuth7/deploy-a-laravel-app-on-hostinger-using-git-1ice</guid>
      <description>&lt;p&gt;This tutorial talks about how to deploy a Laravel app on Hostinger Hpanel. And I'm talking about adding Node JS (Via NVM) build using composer and may more interesting things.&lt;/p&gt;

&lt;p&gt;Here we imagine you use popular business plan on hostinger. But deploying on other plans are also same&lt;/p&gt;

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

&lt;h2&gt;
  
  
  &lt;strong&gt;1. Create a website on hostinger&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Got to websites list, click &lt;strong&gt;"Add Website"&lt;/strong&gt; button and select &lt;strong&gt;"Empty PHP/HTML website"&lt;/strong&gt; from dropdown&lt;/p&gt;

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

&lt;p&gt;After that you will be redirected to that domains dashboard. Inside this dashboard go to &lt;strong&gt;"Advanced -&amp;gt; SSH Access"&lt;/strong&gt; and enable SSH status. And don't forget to add a password.&lt;/p&gt;

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

&lt;p&gt;Then login with putty using these data.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;2. Adding relevant aspects such as database creation and Node.js setup.&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We are going to add relevant aspects. And let us start with database creation. First go to &lt;strong&gt;"Databases -&amp;gt; Management"&lt;/strong&gt; section in your website dashboard and create a &lt;strong&gt;Database and a User&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;Now database has created. Lets login to putty and get node installed.&lt;/p&gt;

&lt;p&gt;To install Node.js on Hostinger using NVM (Node Version Manager), follow these steps:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Install NVM (Node Version Manager)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Download and install NVM using cURL:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Reload your shell configuration to apply changes:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify NVM installation:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; nvm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If installed correctly, it should return &lt;code&gt;nvm&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Install Node.js Using NVM&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;List available Node.js versions:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   nvm list-remote
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install the latest &lt;strong&gt;LTS&lt;/strong&gt; version:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   nvm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--lts&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Set the installed version as the default:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   nvm use &lt;span class="nt"&gt;--lts&lt;/span&gt;
   nvm &lt;span class="nb"&gt;alias &lt;/span&gt;default node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify the Node.js and npm versions:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   node &lt;span class="nt"&gt;-v&lt;/span&gt;
   npm &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should display the installed versions of Node.js and npm.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 3: Keep Node.js Available for All Sessions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Since Hostinger’s shared hosting resets the environment on logout, add the following line to &lt;code&gt;~/.bashrc&lt;/code&gt; or &lt;code&gt;~/.bash_profile&lt;/code&gt; to auto-load NVM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;NVM_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.nvm"&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NVM_DIR&lt;/span&gt;&lt;span class="s2"&gt;/nvm.sh"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\.&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NVM_DIR&lt;/span&gt;&lt;span class="s2"&gt;/nvm.sh"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, reload the shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, Node.js should work consistently across sessions.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;3. Clone the website and get it running&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Again login to putty. And go to your website directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /home/youruser/domains/yourdomain.hostingersite.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;User and domain can be easily found on website dashboard on Hostinger.&lt;/p&gt;

&lt;p&gt;And then remove the &lt;strong&gt;public_html&lt;/strong&gt; folder inside. Actually we are removing everything inside the folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rm -rf /home/u749865644/domains/saddlebrown-spider-721569.hostingersite.com/*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;I know public_html folder is needed in Hostinger hosting. But it's existence will make it hard to clone and deploy a Laravel app. We will add a public_html with a neat trick later&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now we should clone the Laravel app to your domain folder from git.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/your-git/your-repo.git .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the folder is empty we can easily clone our app here. And if your repository is private, try using a personal access token. &lt;/p&gt;

&lt;p&gt;Now lets do a composer install. But there is an important point. &lt;strong&gt;Hostinger has installed both composer 1 and composer 2. And we need composer 2.&lt;/strong&gt; So our command should look like this&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Then install node packages.&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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now let's create the .env&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cp .env.example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;And don't forget to update that .env using 'nano .env' to access the db we created earlier.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;DB_CONNECTION=mysql&lt;br&gt;
DB_HOST=127.0.0.1&lt;br&gt;
DB_PORT=3306&lt;br&gt;
DB_DATABASE=hostingeruser&lt;br&gt;
DB_USERNAME=hostingerdb&lt;br&gt;
DB_PASSWORD=hostingerpassword&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And make note that we can keep DB_HOST and DB_CONNECTION&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now lets generate keys.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan key:generate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now let's run migrate and seed commands. And remember if there is an error, check weather password contains special characters and if so include it inside double quotes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DB_PASSWORD="hostingerpassword&amp;amp;$#@"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan migrate
php artisan db:seed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now lets create symbolic links. But there is a small alteration. If you run &lt;strong&gt;php artisan storage:link&lt;/strong&gt; command there will be an error. &lt;/p&gt;

&lt;p&gt;This error occurs because Hostinger disables the symlink() function for security reasons. Laravel uses symlink() to create a symbolic link from public/storage to storage/app/public when running above command. &lt;/p&gt;

&lt;p&gt;So you will have to manually Create a Storage Link Using a Hard Link&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ln -s /home/youruser/yourdomain.hostingersite.com/storage/app/public /home/youruser/yourdomain.hostingersite.com/public/storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is just a linux command to create a symlink or shortcut. just replace 'youruser' and 'yourdomain'.&lt;/p&gt;

&lt;p&gt;now we have another important thing. Hostinger needs &lt;strong&gt;public_html&lt;/strong&gt; to host and laravel needs &lt;strong&gt;public&lt;/strong&gt;. To satisfy both what we can do is &lt;strong&gt;create a public_html symbolic link which will be linked to public folder&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;ln -s public public_html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now let's run npm build&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your website is ready. Build something useful and make the world a better place and make me proud. Cheers&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>hostinger</category>
    </item>
    <item>
      <title>Understanding var and let in JavaScript: When and Why to Use Each for Cleaner Code</title>
      <dc:creator>vimuth</dc:creator>
      <pubDate>Sat, 26 Oct 2024 10:28:54 +0000</pubDate>
      <link>https://dev.to/vimuth7/understanding-var-and-let-in-javascript-when-and-why-to-use-each-for-cleaner-code-2hjb</link>
      <guid>https://dev.to/vimuth7/understanding-var-and-let-in-javascript-when-and-why-to-use-each-for-cleaner-code-2hjb</guid>
      <description>&lt;p&gt;In JavaScript, variable declarations are fundamental, but choosing between var, let, and const can greatly impact code quality. Understanding when and why to use each helps create cleaner, more predictable code, essential for modern development.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var&lt;/code&gt; and &lt;code&gt;let&lt;/code&gt; are both used to declare variables in JavaScript, but they have some key differences in how they handle &lt;strong&gt;scope&lt;/strong&gt;, &lt;strong&gt;hoisting&lt;/strong&gt;, and &lt;strong&gt;re-declaration&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Differences Between &lt;code&gt;var&lt;/code&gt; and &lt;code&gt;let&lt;/code&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;var&lt;/code&gt;&lt;/strong&gt; is &lt;strong&gt;function-scoped&lt;/strong&gt;: When you declare a variable with &lt;code&gt;var&lt;/code&gt;, it’s accessible throughout the entire function in which it’s declared.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;let&lt;/code&gt;&lt;/strong&gt; is &lt;strong&gt;block-scoped&lt;/strong&gt;: Variables declared with &lt;code&gt;let&lt;/code&gt; are only accessible within the block (e.g., &lt;code&gt;{...}&lt;/code&gt;) where they are defined, making it safer to use in most cases.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Hoisting&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Both &lt;code&gt;var&lt;/code&gt; and &lt;code&gt;let&lt;/code&gt; are &lt;strong&gt;hoisted&lt;/strong&gt; to the top of their scope, but &lt;code&gt;let&lt;/code&gt; is in a &lt;strong&gt;Temporal Dead Zone&lt;/strong&gt; (TDZ) until the line where it’s defined, meaning you cannot access it before its declaration.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;var&lt;/code&gt;, on the other hand, is hoisted without the TDZ, so it’s accessible throughout its scope (though it will be &lt;code&gt;undefined&lt;/code&gt; until its declaration).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Re-declaration&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;var&lt;/code&gt;&lt;/strong&gt; allows re-declaration of the same variable in the same scope, which can lead to unintended bugs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;let&lt;/code&gt;&lt;/strong&gt; does not allow re-declaration in the same scope, helping avoid accidental overwrites.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Example 1: Scope Difference
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;testVar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&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="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;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Same `x` in function scope, reassigns the outer `x`&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Inside if-block:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Output: 20&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Outside if-block:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Output: 20 (still the same `x`)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;testVar&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;With &lt;code&gt;let&lt;/code&gt;:&lt;/strong&gt;&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;function&lt;/span&gt; &lt;span class="nf"&gt;testLet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&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="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;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// New `y` scoped to this block only&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Inside if-block:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Output: 20&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Outside if-block:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Output: 10 (outer `y` is unchanged)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;testLet&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;testVar&lt;/code&gt; function, &lt;code&gt;var&lt;/code&gt; declares a single &lt;code&gt;x&lt;/code&gt; for the entire function scope, so reassigning &lt;code&gt;x&lt;/code&gt; inside the &lt;code&gt;if&lt;/code&gt; block also changes it outside the block. With &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt; inside the &lt;code&gt;if&lt;/code&gt; block is a separate variable from &lt;code&gt;y&lt;/code&gt; outside, preserving each &lt;code&gt;y&lt;/code&gt;'s value in its own scope.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 2: Hoisting Difference
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hoistVar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Output: undefined (due to hoisting)&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Output: 10&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;hoistVar&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;With &lt;code&gt;let&lt;/code&gt;:&lt;/strong&gt;&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;function&lt;/span&gt; &lt;span class="nf"&gt;hoistLet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Error: Cannot access 'y' before initialization&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// This line would not be reached&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;hoistLet&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;hoistVar&lt;/code&gt;, &lt;code&gt;var x&lt;/code&gt; is hoisted to the top of the function scope, but it’s &lt;code&gt;undefined&lt;/code&gt; until the actual assignment. In &lt;code&gt;hoistLet&lt;/code&gt;, trying to access &lt;code&gt;y&lt;/code&gt; before it’s assigned results in a &lt;strong&gt;ReferenceError&lt;/strong&gt; because &lt;code&gt;let&lt;/code&gt; variables are hoisted but remain in a &lt;strong&gt;Temporal Dead Zone (TDZ)&lt;/strong&gt; until their declaration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 3: Re-declaration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;redeclareVar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Allowed with `var`&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Output: 10&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;redeclareVar&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;With &lt;code&gt;let&lt;/code&gt;:&lt;/strong&gt;&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;function&lt;/span&gt; &lt;span class="nf"&gt;redeclareLet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Error: Identifier 'y' has already been declared&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;redeclareLet&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;code&gt;var&lt;/code&gt;, re-declaring &lt;code&gt;x&lt;/code&gt; in the same scope is allowed, which could cause unintended bugs. With &lt;code&gt;let&lt;/code&gt;, re-declaring &lt;code&gt;y&lt;/code&gt; in the same scope results in an error, helping to avoid accidental overwrites.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scope&lt;/strong&gt;: &lt;code&gt;var&lt;/code&gt; is function-scoped; &lt;code&gt;let&lt;/code&gt; is block-scoped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hoisting&lt;/strong&gt;: &lt;code&gt;var&lt;/code&gt; is hoisted without restriction, while &lt;code&gt;let&lt;/code&gt; is in a Temporal Dead Zone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Re-declaration&lt;/strong&gt;: &lt;code&gt;var&lt;/code&gt; allows it; &lt;code&gt;let&lt;/code&gt; does not.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In general, &lt;code&gt;let&lt;/code&gt; is recommended in modern JavaScript because it provides more predictable scoping and reduces the risk of unintended bugs.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Understanding Two-Way Data Binding in Vue 3: Creating Child Components, Passing Data to Parents, and Attribute Inheritance</title>
      <dc:creator>vimuth</dc:creator>
      <pubDate>Sat, 07 Sep 2024 21:12:39 +0000</pubDate>
      <link>https://dev.to/vimuth7/understanding-two-way-data-binding-in-vue-3-creating-child-components-passing-data-to-parents-and-attribute-inheritance-36e5</link>
      <guid>https://dev.to/vimuth7/understanding-two-way-data-binding-in-vue-3-creating-child-components-passing-data-to-parents-and-attribute-inheritance-36e5</guid>
      <description>&lt;p&gt;In modern web development, efficient component design and seamless data communication are crucial for building interactive and maintainable user interfaces. Vue 3, with its Composition API and &lt;code&gt;&amp;lt;script setup&amp;gt;&lt;/code&gt; syntax, introduces powerful tools to streamline component creation and data handling. One key feature of Vue 3 is attribute inheritance, which simplifies the management of dynamic attributes in components.&lt;/p&gt;

&lt;p&gt;In this article, we will explore how to create child components in Vue 3, pass data between parent and child components, and leverage attribute inheritance for a more flexible and cleaner component design. We will cover practical examples and best practices to help you harness the full potential of Vue 3's capabilities, making your development process more intuitive and efficient.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a Simple TextArea Component
&lt;/h3&gt;

&lt;p&gt;Create a new Vue component file named TextArea.vue with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;textarea
    :value="modelValue"
    @input="handleInput"
  &amp;gt;&amp;lt;/textarea&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
import { defineProps, defineEmits } from 'vue';

const props = defineProps({
  modelValue: String
});

const emit = defineEmits(['update:modelValue']);

const handleInput = (event) =&amp;gt; {
  emit('update:modelValue', event.target.value);
};
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s an example of how you can use the TextArea component in a parent component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;TextArea v-model="commentBody" /&amp;gt;
    &amp;lt;p&amp;gt;Your comment: {{ commentBody }}&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
import { ref } from 'vue';
import TextArea from './TextArea.vue'; // Adjust the path as needed

// Define a ref to hold the textarea value
const commentBody = ref('');
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now watch carefully. We don't need to emit update value element from child component. Vue 3 does this for us.&lt;/p&gt;

&lt;p&gt;Parent Component Listens for the update:modelValue Event: The parent component listens for the update:modelValue event because of the v-model directive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;TextArea v-model="commentBody" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vue internally converts this v-model into the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;TextArea :modelValue="commentBody" @update:modelValue="val =&amp;gt; commentBody = val" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means that whenever the update:modelValue event is emitted from the child component, the parent updates its commentBody variable with the new value (the value the user typed).&lt;/p&gt;

&lt;p&gt;This two-way binding mechanism is how the data flows between the parent and the child component in Vue.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding Attribute Inheritance
&lt;/h3&gt;

&lt;p&gt;In Vue 3, any extra attributes (like class, id, or style) passed to a component that are not explicitly defined in props are automatically added to the root element of the template by default. This feature is known as attribute inheritance or attribute forwarding. This is a really cool and useful feature.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;TextArea v-model="commentBody" class="textclass" id="textid"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you pass attributes like class or id, they  automatically to the root element of a component.&lt;/p&gt;

&lt;p&gt;In this example they (class and id) will apply to the &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt; (root of child component) element.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>test</title>
      <dc:creator>vimuth</dc:creator>
      <pubDate>Sat, 07 Sep 2024 19:24:02 +0000</pubDate>
      <link>https://dev.to/vimuth7/test-54gg</link>
      <guid>https://dev.to/vimuth7/test-54gg</guid>
      <description>&lt;p&gt;In modern web development, efficient component design and seamless data communication are crucial for building interactive and maintainable user interfaces. Vue 3, with its Composition API and  syntax, introduces powerful tools to streamline component creation and data handling. One key feature of Vue 3 is attribute inheritance, which simplifies the management of dynamic attributes in components.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;In this article, we will explore how to create child components in Vue 3, pass data between parent and child components, and leverage attribute inheritance for a more flexible and cleaner component design. We will cover practical examples and best practices to help you harness the full potential of Vue 3&amp;amp;#39;s capabilities, making your development process more intuitive and efficient.&amp;lt;/p&amp;gt;
&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Understanding Mass Assignment in Laravel: How fillable Protects Your Models</title>
      <dc:creator>vimuth</dc:creator>
      <pubDate>Sat, 07 Sep 2024 09:43:06 +0000</pubDate>
      <link>https://dev.to/vimuth7/understanding-mass-assignment-in-laravel-how-fillable-protects-your-models-2n4c</link>
      <guid>https://dev.to/vimuth7/understanding-mass-assignment-in-laravel-how-fillable-protects-your-models-2n4c</guid>
      <description>&lt;p&gt;In Laravel, mass assignment allows you to quickly create or update records by passing an array of attributes. While convenient, it can also expose your application to security risks if not handled correctly. That’s where the fillable property comes in—it ensures that only specific fields can be mass-assigned, protecting sensitive data. This article explains how fillable works, its advantages, and why it doesn’t apply when using the save() method and how to avoid this fillable if don't need that.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is &lt;strong&gt;Mass Assignment&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Mass assignment refers to assigning multiple attributes to a model at once using an array. It usually happens in one of the following ways:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Using create():&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;// Creating two users using mass assignment
User::create([
    'name' =&amp;gt; 'Alice',
    'email' =&amp;gt; 'alice@example.com',
    'password' =&amp;gt; bcrypt('password123')
]);

User::create([
    'name' =&amp;gt; 'Bob',
    'email' =&amp;gt; 'bob@example.com',
    'password' =&amp;gt; bcrypt('secret456')
]);

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

&lt;/div&gt;



&lt;p&gt;In this example, both create() calls use mass assignment to set multiple attributes at once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Using update():&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;// Finding two users and updating their information using mass assignment
$user1 = User::find(1);
$user1-&amp;gt;update([
    'name' =&amp;gt; 'Alice Updated',
    'email' =&amp;gt; 'alice_new@example.com'
]);

$user2 = User::find(2);
$user2-&amp;gt;update([
    'name' =&amp;gt; 'Bob Updated',
    'email' =&amp;gt; 'bob_new@example.com'
]);

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

&lt;/div&gt;



&lt;p&gt;Here, the update() method allows multiple fields to be updated at once through mass assignment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Issues of &lt;strong&gt;Mass Assignment&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Using mass assignment without proper controls can introduce serious security vulnerabilities. Consider the following example in your controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function store(Request $request)
{
    // This allows all fields from the request to be mass-assigned
    User::create($request-&amp;gt;all());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is risky. Imagine request have this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "name": "Alice",
    "email": "alice@example.com",
    "password": "password123",
    "is_admin": true,
    "status": "active"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Imagine they are adding an &lt;strong&gt;Admin&lt;/strong&gt; and change everything. This can lead to unauthorized privilege escalation or unintended account modifications.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;fillable&lt;/strong&gt; Array and how it prevents this issues
&lt;/h3&gt;

&lt;p&gt;To prevent mass assignment of sensitive fields like is_admin and status, you can specify which fields are allowed for mass assignment using the fillable array in the User model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class User extends Model
{
    // Define the fields that are allowed for mass assignment
    protected $fillable = ['name', 'email', 'password'];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the fillable array defined as shown above, only the attributes listed in the array can be mass-assigned. This means that even if a request contains fields like is_admin or status, they will be ignored when using mass assignment methods like create() or update().&lt;/p&gt;

&lt;h3&gt;
  
  
  Notes to consider.
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;insert() method not considering fillables.&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;insert() is a query builder method, not an Eloquent model method, so it bypasses Eloquent's features like mass assignment protection, events, and model accessors/mutators.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User::insert([
    [
        'name' =&amp;gt; 'Alice',
        'email' =&amp;gt; 'alice@example.com',
        'password' =&amp;gt; bcrypt('password123')
    ],
    [
        'name' =&amp;gt; 'Bob',
        'email' =&amp;gt; 'bob@example.com',
        'password' =&amp;gt; bcrypt('secret456')
    ]
]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;u&gt;&lt;strong&gt;Ignore fillable array if needed.&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;If you need to bypass the &lt;code&gt;fillable&lt;/code&gt; array for a specific operation, you can use the &lt;code&gt;unguard()&lt;/code&gt; method provided by Laravel's Eloquent model. This method allows you to disable mass assignment protection temporarily.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to Use &lt;code&gt;unguard()&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Disable Mass Assignment Protection:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can use &lt;code&gt;Model::unguard()&lt;/code&gt; to disable mass assignment protection for the entire application or a specific block of code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enable Mass Assignment Protection Again:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After performing the operations where mass assignment protection is not needed, you should call &lt;code&gt;Model::reguard()&lt;/code&gt; to re-enable it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Example Usage:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Temporarily Disable Mass Assignment Protection&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;use Illuminate\Database\Eloquent\Model;

public function store(Request $request)
{
    // Temporarily disable mass assignment protection
    Model::unguard();

    // Validate the request data (if needed)
    $validatedData = $request-&amp;gt;validate([
        'name' =&amp;gt; 'required|string|max:255',
        'email' =&amp;gt; 'required|email|unique:users,email',
        'password' =&amp;gt; 'required|string|min:8',
    ]);

    // Prepare data for insertion
    $userData = [
        'name' =&amp;gt; $validatedData['name'],
        'email' =&amp;gt; $validatedData['email'],
        'password' =&amp;gt; bcrypt($validatedData['password']),
        'is_admin' =&amp;gt; $request-&amp;gt;input('is_admin'),  // Example of bypassing fillable
        'status' =&amp;gt; $request-&amp;gt;input('status'),      // Example of bypassing fillable
        'created_at' =&amp;gt; now(),
        'updated_at' =&amp;gt; now(),
    ];

    // Insert the record
    User::insert($userData);

    // Re-enable mass assignment protection
    Model::reguard();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Points:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use with Caution&lt;/strong&gt;: &lt;code&gt;unguard()&lt;/code&gt; bypasses the fillable protection, so use it carefully. Ensure that you validate and sanitize the data properly before inserting it into the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scope of &lt;code&gt;unguard()&lt;/code&gt;&lt;/strong&gt;: It affects all models in the application during its scope. If you only need to bypass fillable protection for specific models or operations, it's better to handle it at the model level or within a specific code block.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Re-enable Protection&lt;/strong&gt;: Always call &lt;code&gt;Model::reguard()&lt;/code&gt; after performing operations that require &lt;code&gt;unguard()&lt;/code&gt; to ensure that mass assignment protection is re-enabled for the rest of your application.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Database optimizing with Hugh datasets with MySQL.</title>
      <dc:creator>vimuth</dc:creator>
      <pubDate>Thu, 05 Sep 2024 17:15:57 +0000</pubDate>
      <link>https://dev.to/vimuth7/database-optimizing-with-hugh-datasets-with-mysql-344k</link>
      <guid>https://dev.to/vimuth7/database-optimizing-with-hugh-datasets-with-mysql-344k</guid>
      <description>&lt;p&gt;Efficient database performance is crucial for any application, and optimizing MySQL queries plays a key role in achieving that. As data grows, poorly written queries can cause significant slowdowns, leading to longer response times and higher resource consumption. By understanding how MySQL executes queries and applying optimization techniques like indexing, query restructuring, and proper data types, you can dramatically improve performance. Whether you’re handling small datasets or scaling to millions of records, optimized queries ensure smoother and faster interactions with your database, ultimately improving the user experience and reducing server load.&lt;/p&gt;

&lt;p&gt;My database contains an &lt;code&gt;employees&lt;/code&gt; table with approximately 7,852,118 rows.&lt;/p&gt;

&lt;p&gt;I executed the following query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * 
FROM employees
WHERE email = 'sbrakus@example.org'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The query took roughly 17 seconds to execute, though this duration may vary depending on server conditions.&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%2Fk6g7tl9d13m45mrlgvqw.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%2Fk6g7tl9d13m45mrlgvqw.png" alt="Image description" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimizing Queries by Selecting Only Relevant Fields
&lt;/h2&gt;

&lt;p&gt;Selecting only the necessary fields, rather than retrieving all columns, can significantly reduce query execution time. Consider the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT email 
FROM employees
WHERE email = 'sbrakus@example.org' 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Ffsqsz4nepmpsnlzahkhz.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%2Ffsqsz4nepmpsnlzahkhz.png" alt="Image description" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Improving Performance with Indexing
&lt;/h2&gt;

&lt;p&gt;One of the most effective ways to speed up queries is by using indexing. Let's start by creating an index on the &lt;code&gt;email&lt;/code&gt; column:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE INDEX idx_employees_email ON employees(email);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when we run the same query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT email 
FROM employees
WHERE email = 'sbrakus@example.org';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The query should execute much faster, as the index allows MySQL to quickly locate the relevant records.&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%2Fdetj92chc2qlbqtmrbpe.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%2Fdetj92chc2qlbqtmrbpe.png" alt="Image description" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You’ll notice that the query now executes in just 0.020 seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Addressing Indexing Limitations and Query Optimization
&lt;/h2&gt;

&lt;p&gt;While indexing significantly improved the performance of queries on the &lt;code&gt;email&lt;/code&gt; field, it doesn't impact queries that filter on non-indexed fields. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT email 
FROM employees
WHERE last_name = 'Halvorson';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fosvktoskscsbx9u06klu.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%2Fosvktoskscsbx9u06klu.png" alt="Image description" width="800" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This query will still be slow because &lt;code&gt;last_name&lt;/code&gt; is not indexed. Similarly, fetching all records from the &lt;code&gt;employees&lt;/code&gt; table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * 
FROM employees;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Can be very time-consuming, especially with a large dataset.&lt;/p&gt;

&lt;p&gt;To manage large result sets, consider using limits to restrict the number of rows returned:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt; 
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="k"&gt;OFFSET&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach can help to retrieve data in smaller, more manageable chunks, reducing the load on your server and improving performance.&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%2Fxu5eyj90evbnut9o8c9f.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%2Fxu5eyj90evbnut9o8c9f.png" alt="Image description" width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Limitations of Query Limiting
&lt;/h2&gt;

&lt;p&gt;Using the &lt;code&gt;LIMIT&lt;/code&gt; clause to restrict the number of records returned can be effective in many scenarios, but it may not always yield the desired results. For instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * 
FROM employees 
WHERE last_name = 'Halvorson'
LIMIT 1000 OFFSET 0;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, the query took 0.348 seconds to complete. The reduced execution time was due to the fact that 'Halvorson' is a relatively common last name. The query was able to stop early, having found 1,000 matching records before scanning the entire table. However, this approach may not be as effective in cases where the filtered criteria are less common or where data distribution is uneven.&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%2Fb3veqat4vdy7j0h9u94t.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%2Fb3veqat4vdy7j0h9u94t.png" alt="Image description" width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Consider this query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * 
FROM employees 
WHERE last_name = 'david'
LIMIT 1000 OFFSET 0;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since 'david' does not exist in the &lt;code&gt;employees&lt;/code&gt; table, the query had to scan all 7,852,118 records, resulting in a significantly longer execution time.&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%2F1z93ms4xq48v6m1mapxw.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%2F1z93ms4xq48v6m1mapxw.png" alt="Image description" width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adding an Index&lt;/p&gt;

&lt;p&gt;Let's create an index on the &lt;code&gt;last_name&lt;/code&gt; field to improve query performance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE INDEX idx_last_name ON employees(last_name);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the new index in place, executing the following query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * 
FROM employees 
WHERE last_name = 'david'
LIMIT 1000 OFFSET 0;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Runs significantly faster. The index allows MySQL to quickly locate relevant records, reducing the time needed to scan the entire table.&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%2Fusljd2l3hs3xbypvcc0l.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%2Fusljd2l3hs3xbypvcc0l.png" alt="Image description" width="800" height="299"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, this B-tree index has its limitations. While it performs well with queries where the search string begins with a specific prefix, such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM employees
WHERE last_name LIKE 'david%';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, MySQL can efficiently use the index to find &lt;code&gt;last_name&lt;/code&gt; values starting with "david."&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%2Fjmpw2qobvdsmq4cg7mf7.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%2Fjmpw2qobvdsmq4cg7mf7.png" alt="Image description" width="800" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But for &lt;code&gt;LIKE&lt;/code&gt; queries with different wildcards, such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM employees
WHERE last_name LIKE '%david';

SELECT * FROM employees
WHERE last_name LIKE '%david%';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fmdf6v8j0yev0imh1yaqs.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%2Fmdf6v8j0yev0imh1yaqs.png" alt="Image description" width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The index may not be used effectively, resulting in slower query performance. &lt;/p&gt;

&lt;p&gt;In these cases, MySQL indexes may not be sufficient. I will provide a tutorial on PostgreSQL indexing techniques to address these limitations.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Mastering User Experience: Understanding and Implementing Debouncing and Throttling in JavaScript</title>
      <dc:creator>vimuth</dc:creator>
      <pubDate>Tue, 27 Aug 2024 17:23:50 +0000</pubDate>
      <link>https://dev.to/vimuth7/mastering-user-experience-understanding-and-implementing-debouncing-and-throttling-in-javascript-26jo</link>
      <guid>https://dev.to/vimuth7/mastering-user-experience-understanding-and-implementing-debouncing-and-throttling-in-javascript-26jo</guid>
      <description>&lt;p&gt;In the fast-paced world of web development, user experience is paramount. One of the key aspects of ensuring a smooth and responsive interface is managing how and when events are processed. This is where debouncing and throttling come into play. These techniques are crucial for optimizing performance and enhancing the user experience by controlling the rate at which functions are executed. Whether you're dealing with input fields that trigger search queries, scrolling events, or resizing actions, understanding and implementing debouncing and throttling can make a significant difference in the responsiveness and efficiency of your web applications. In this article, we'll explore the concepts of debouncing and throttling, their differences, and practical implementations in JavaScript to help you master user experience design.&lt;/p&gt;

&lt;p&gt;I'll explain them simple. Here's an example of making an API call with an input field using jQuery without using &lt;strong&gt;Lodash&lt;/strong&gt;. This example will simulate making a call to a dummy API every time the user types something in the input field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;label for="inputField"&amp;gt;Type something:&amp;lt;/label&amp;gt;
    &amp;lt;input type="text" id="inputField"&amp;gt;

    &amp;lt;h2&amp;gt;API Response:&amp;lt;/h2&amp;gt;
    &amp;lt;p id="apiResponse"&amp;gt;&amp;lt;/p&amp;gt;

    &amp;lt;script src="https://code.jquery.com/jquery-3.6.0.min.js"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script&amp;gt;
        $(document).ready(function() {
            $('#inputField').on('input', function() {
                const value = $(this).val();

                // Make the API call when the input value changes
                $.ajax({
                    url: `https://jsonplaceholder.typicode.com/posts?q=${value}`,
                    method: 'GET',
                    success: function(response) {
                        $('#apiResponse').text(JSON.stringify(response));
                    },
                    error: function() {
                        $('#apiResponse').text('Error fetching data.');
                    }
                });
            });
        });
    &amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you check inspect element you will see that an API call goes to a server every time we type a letter.&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%2Fb5nsqryrx9822z0bogbu.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%2Fb5nsqryrx9822z0bogbu.png" alt="Image description" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's true that we need the result for "example post". But we don't need to send API call and get results for e, ex, exa or exam. &lt;strong&gt;For that we can use Debouncing and Throttling&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Debouncing
&lt;/h2&gt;

&lt;p&gt;debouncing ensures that a function is executed only after a certain period of inactivity, reducing the number of function calls and improving performance. Let me explain it further.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const debouncedUpdate = _.debounce(function (value) {
                $('#debouncedOutput').text(value);
                console.log('Debounced Input:', value);
            }, 1000); // 1 second debounce
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They wait 1000 milisecond or 1 second before send the API call. (Or change text in $('#debouncedOutput') according to this case). &lt;/p&gt;

&lt;p&gt;Even though you sent three API calls for this, 'exa' now it waits 1 second (1000 milliseconds) after pressing first letter before sending an API call. If you press second letter before that API call will not go. &lt;/p&gt;

&lt;p&gt;If you type into a search box, the function debouncedUpdate will wait for 1 second after the user stops typing before executing. So, if the user types "exa" and then types more characters within that second, the debounce delay resets and the function won’t execute until the user stops typing for a full second. This prevents unnecessary function calls or updates while the user is still typing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Throttling
&lt;/h2&gt;

&lt;p&gt;Check this example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const throttledUpdate = _.throttle(function (value) {
                $('#throttledOutput').text(value);
                console.log('Throttled Input:', value);
            }, 1000); // 1 second throttle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Throttling works like this. After you start typing after every 1000 milliseconds the function runs until stop typing. And make note it will run initial call too.  &lt;/p&gt;

&lt;p&gt;Here’s how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Initial Call:&lt;/strong&gt; When the event first occurs (e.g., typing), the function executes immediately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subsequent Calls:&lt;/strong&gt; The function will not execute again until the specified interval (e.g., 1000 milliseconds) has passed, even if the event continues to occur during that time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interval Execution:&lt;/strong&gt; After the interval has passed, if there are additional events, the function will execute again and then wait for the next interval.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, throttling limits how frequently the function is executed during continuous events, ensuring it only runs at a controlled rate.&lt;/p&gt;

&lt;p&gt;This is a complete example if you want to check the behavior more&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;

&amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
    &amp;lt;title&amp;gt;Lodash Throttle and Debounce Example&amp;lt;/title&amp;gt;

&amp;lt;/head&amp;gt;

&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Lodash Throttle and Debounce Example&amp;lt;/h1&amp;gt;

    &amp;lt;label for="inputField"&amp;gt;Type something:&amp;lt;/label&amp;gt;
    &amp;lt;input type="text" id="inputField"&amp;gt;

    &amp;lt;h2&amp;gt;Throttled Output:&amp;lt;/h2&amp;gt;
    &amp;lt;p id="throttledOutput"&amp;gt;&amp;lt;/p&amp;gt;

    &amp;lt;h2&amp;gt;Debounced Output:&amp;lt;/h2&amp;gt;
    &amp;lt;p id="debouncedOutput"&amp;gt;&amp;lt;/p&amp;gt;

    &amp;lt;!-- jQuery CDN --&amp;gt;
    &amp;lt;script src="https://code.jquery.com/jquery-3.6.0.min.js"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;!-- Lodash CDN --&amp;gt;
    &amp;lt;script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script&amp;gt;
        $(document).ready(function () {
            // Throttle example: Limits the number of times the function can execute within a time frame
            const throttledUpdate = _.throttle(function (value) {
                $('#throttledOutput').text(value);
                console.log('Throttled Input:', value);
            }, 1000); // 1 second throttle

            // Debounce example: Delays the execution of the function until a certain amount of time has passed without triggering
            const debouncedUpdate = _.debounce(function (value) {
                $('#debouncedOutput').text(value);
                console.log('Debounced Input:', value);
            }, 1000); // 1 second debounce

            // Event listener for input field
            $('#inputField').on('input', function () {
                const value = $(this).val();
                throttledUpdate(value);
                debouncedUpdate(value);
            });
        });
    &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;

&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Eager loading, n+1 issue and query optimization in laravel</title>
      <dc:creator>vimuth</dc:creator>
      <pubDate>Tue, 27 Aug 2024 08:22:18 +0000</pubDate>
      <link>https://dev.to/vimuth7/eager-loading-n1-issue-and-query-optimization-in-laravel-5555</link>
      <guid>https://dev.to/vimuth7/eager-loading-n1-issue-and-query-optimization-in-laravel-5555</guid>
      <description>&lt;p&gt;In Laravel there are few ways to optimize queries. One way is eager loading. First let's see what is eager loading. &lt;/p&gt;

&lt;p&gt;When you handle relationships between columns, The default way is Lazy loading. When you access a related model in Laravel, a separate query is made to the database to fetch that related data. This is known as lazy loading. Let us see with and example.&lt;/p&gt;

&lt;p&gt;Assume you have two models: &lt;strong&gt;Post&lt;/strong&gt; and &lt;strong&gt;Comment&lt;/strong&gt;, where &lt;strong&gt;a Post has many Comments&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;$posts = Post::all();

foreach ($posts as $post) {
    foreach ($post-&amp;gt;comments as $comment) {
        // Each iteration fetches comments in a separate query
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us now see how this works in query level. Imagine you have &lt;strong&gt;N&lt;/strong&gt; number of posts in your table. Above code will run N+1 queries. Let me explain how it happens,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;First Query: Fetch All Posts&lt;/u&gt;&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;SELECT * FROM `posts`;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;u&gt;N Queries: Fetch Comments for Each Post&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;
For each Post object in $posts, Laravel will perform a separate query to fetch the related comments. If there are "N" posts, it will run "N" queries, one for each post.&lt;/p&gt;

&lt;p&gt;The query structure looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM `comments` WHERE `comments`.`post_id` = 1 AND `comments`.`post_id` IS NOT NULL;
SELECT * FROM `comments` WHERE `comments`.`post_id` = 2 AND `comments`.`post_id` IS NOT NULL;
...
SELECT * FROM `comments` WHERE `comments`.`post_id` = N AND `comments`.`post_id` IS NOT NULL;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;u&gt;Summary of Queries:&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;1 Query to fetch all posts from the posts table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;N Queries to fetch comments for each post, where N is the number of posts retrieved in the first query.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you may see there are N+1 queries. This is called N+1 issue. For prevent this we use &lt;strong&gt;Eager Loading&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Eager Loading
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$posts = Post::with('comments')-&amp;gt;get();

foreach ($posts as $post) {
    foreach ($post-&amp;gt;comments as $comment) {
        // Comments are already loaded
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we use "with" eloquent method for eager loading. Let's see how this optimize things. Instead of N+1 queries it runs only two queries now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Query to Fetch All Posts:&lt;/u&gt;&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;SELECT * FROM `posts`;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;u&gt;Query to Fetch All Related Comments:&lt;/u&gt;&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;SELECT * FROM `comments` WHERE `post_id` IN (1, 2, 3, ... , N);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of N+1 queries in earlier now we have only two queries. And this increases the performance a lot. &lt;/p&gt;

&lt;h2&gt;
  
  
  After Eager Loading
&lt;/h2&gt;

&lt;p&gt;In some cases also &lt;strong&gt;Eager Loading&lt;/strong&gt; may be problematic. Let's see an example. Imagine Post model (posts table) have multiple relationships.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$posts = Post::with(['user', 'comments'])-&amp;gt;get();

foreach ($posts as $post) {

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

&lt;/div&gt;



&lt;p&gt;This will result in three queries. &lt;strong&gt;Fetch posts, users related to posts and comments related to posts&lt;/strong&gt;. Imagine you have millions of users and comments in your database. Then it will be better to take all these records using a single query.&lt;/p&gt;

&lt;p&gt;In a scenario like this taking everything inside one query is faster than taking three queries and mapping. The reason is databases has optimized to face such scenarios. In theoretically speaking this is the reason&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single Query&lt;/strong&gt;: Joins allow you to fetch all the related data in a single query, reducing the overhead of multiple database round trips.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database-Level Optimization&lt;/strong&gt;: Joins leverage the database's ability to optimize query execution, often resulting in faster data retrieval, especially with proper indexing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduced Memory Usage&lt;/strong&gt;: Since joins combine data into a single result set, they can be more memory-efficient, especially when you don't need to instantiate many related models in your application.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of using with, you could use a join to fetch the data more efficiently:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$posts = Post::select('posts.*', 'users.name as author_name', 'comments.content as comment_content')
    -&amp;gt;join('users', 'posts.user_id', '=', 'users.id')
    -&amp;gt;join('comments', 'posts.id', '=', 'comments.post_id')
    -&amp;gt;get();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But if you check this query carefully you can see "users.name as author_name" and "comments.content as comment_content". This is because two tables having same column called 'name'. But for eager loading situations like this are automatically handled.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bottom Line:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Joins:&lt;/strong&gt; If you're dealing with multiple relationships and large datasets, using &lt;strong&gt;joins&lt;/strong&gt; can be more efficient. This is because joins consolidate the data retrieval into a single, optimized query, minimizing the overhead of multiple queries and reducing memory usage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Eager Loading:&lt;/strong&gt; If you're not dealing with massive datasets or the relationships aren't too complex, &lt;strong&gt;eager loading&lt;/strong&gt; is a safer and more convenient option. It automatically handles potential conflicts (like duplicate column names) and allows you to work with related models in a clean and organized way without needing to worry about query complexity.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When to Choose Which:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Joins:&lt;/strong&gt; Ideal for scenarios where performance is critical, and you're dealing with large volumes of data. Use joins when you need to minimize the number of queries and optimize database-level operations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Eager Loading:&lt;/strong&gt; Best for smaller or moderate datasets where ease of use and code readability are more important than raw performance. It simplifies working with related data and avoids the manual handling required with joins.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;For &lt;strong&gt;large, complex relationships&lt;/strong&gt;: &lt;strong&gt;Joins&lt;/strong&gt; are typically better for performance.&lt;/li&gt;
&lt;li&gt;For &lt;strong&gt;smaller, simpler scenarios&lt;/strong&gt;: &lt;strong&gt;Eager Loading&lt;/strong&gt; offers convenience and safety.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You could use tools like Laravel Telescope to see the queries and times for them.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Implementing Robust Retry Logic in Laravel Jobs for Reliable API Data Fetching</title>
      <dc:creator>vimuth</dc:creator>
      <pubDate>Mon, 19 Aug 2024 10:11:03 +0000</pubDate>
      <link>https://dev.to/vimuth7/implementing-robust-retry-logic-in-laravel-jobs-for-reliable-api-data-fetching-4ffi</link>
      <guid>https://dev.to/vimuth7/implementing-robust-retry-logic-in-laravel-jobs-for-reliable-api-data-fetching-4ffi</guid>
      <description>&lt;p&gt;Imagine you are fetching data from third party API inside your laravel backend. In modern web applications, integrating with third-party APIs has become commonplace. These external services often provide critical functionalities, from fetching user data to processing transactions. However, these APIs can sometimes fail due to various reasons such as network issues, service outages, or rate limits. Such failures can disrupt your application’s operations and negatively impact user experience.&lt;/p&gt;

&lt;p&gt;To mitigate these risks, it’s essential to implement robust retry mechanisms that can handle these transient failures effectively. This is where Laravel Jobs come into play. Laravel’s job system allows you to perform background tasks asynchronously, including handling API requests. By using jobs, you can ensure that these tasks are retried automatically when they fail, without blocking the main application flow.&lt;/p&gt;

&lt;p&gt;Jobs in Laravel provide a structured way to manage and retry failed tasks, making your application more resilient and reliable. They help offload time-consuming processes from the user’s immediate experience, improving performance and scalability. In this article, we’ll explore how to set up retry logic in Laravel Jobs to handle third-party API failures gracefully, ensuring that your application remains robust and responsive even in the face of external service issues.&lt;/p&gt;

&lt;p&gt;Now let's see how to do this,&lt;/p&gt;

&lt;h1&gt;
  
  
  1.Creating a Job with Retry Logic
&lt;/h1&gt;

&lt;p&gt;First let's create the job with this artisan command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan make:job FetchApiDataJob
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the &lt;strong&gt;retry logic&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;public $tries = 5; // Number of retry attempts
public $backoff = 10; // Seconds to wait before retrying
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the full code for job.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Http;
use App\Models\YourModel; // Replace with your actual model
use Exception;

class FetchApiDataJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $tries = 5; // Number of retry attempts
    public $backoff = 10; // Seconds to wait before retrying

    public function handle()
    {
        try {
            $response = Http::get('https://jsonplaceholder.typicode.com/posts');

            if (!$response-&amp;gt;successful()) {
                throw new Exception('API request failed with status: ' . $response-&amp;gt;status());
            }

            $data = $response-&amp;gt;json();

            foreach ($data as $item) {
                YourModel::updateOrCreate(
                    ['id' =&amp;gt; $item['id']], // Adjust based on your model and data
                    [
                        'title' =&amp;gt; $item['title'],
                        'body' =&amp;gt; $item['body'],
                        // Additional columns
                    ]
                );
            }
        } catch (Exception $e) {
            $this-&amp;gt;fail($e); // Trigger retry
        }
    }

    public function failed(Exception $exception)
    {
        \Log::error('FetchApiDataJob failed: ' . $exception-&amp;gt;getMessage());
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;For any reason if this API call fails and didn't give valid response below if condition fails. And when if condition fails the code throws an exception. And then try catch fails. When try catch fails it runs the API call again according to retry logic we showed before&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;if (!$response-&amp;gt;successful()) {
     throw new Exception('API request failed with status: ' . $response-&amp;gt;status());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  2.Dispatch the Job from a Controller
&lt;/h1&gt;

&lt;p&gt;To dispatch the job from a controller, you would typically do it in response to a user action, such as a form submission or a button click.&lt;/p&gt;

&lt;p&gt;Here’s an example controller method that dispatches the job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace App\Http\Controllers;

use App\Jobs\FetchApiDataJob;
use Illuminate\Http\Request;

class ApiController extends Controller
{
    public function fetchData()
    {
        // Dispatch the job to the queue
        FetchApiDataJob::dispatch();

        // Return a response to the user
        return response()-&amp;gt;json(['message' =&amp;gt; 'Job dispatched to fetch data.']);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  3.Running Queue Workers
&lt;/h1&gt;

&lt;p&gt;Make sure to run this command to run job queues. In server you can use supervisor for this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan queue:work
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  4.Notes.
&lt;/h1&gt;

&lt;p&gt;Imagine this API call takes lots of time to run and slow down the controller. For this also the calling Third party API inside a job is a great solution. And to increase performance more you can use redis queues instead db queues.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
