Optimizing Cursor Animation in jQuery for Smooth Performance

I’m working on a web project where I have implemented a cursor animation using jQuery. The animation involves following the mouse cursor with a delay and ease effect. However, I’ve noticed some lag and I’m looking for ways to optimize the code for smoother performance.

Here’s the current javascript code:

$(document).ready(function () {
  const cursorDot = $('<div class="cursor-dot"></div>').appendTo('body');
  let isHovering = false;

  function updateCursorPos(x, y) {
    if (!isHovering) {
      const ease = 0.2;

      const currentX = cursorDot.position().left;
      const currentY = cursorDot.position().top;

      const newX = currentX + (x - currentX) * ease;
      const newY = currentY + (y - currentY) * ease;

      cursorDot.css({
        left: newX,
        top: newY
      });
    }
  }

  function handleMouseMove(e) {
    const adjustedX = e.pageX - window.pageXOffset;
    const adjustedY = e.pageY - window.pageYOffset;

    requestAnimationFrame(() => {
      updateCursorPos(adjustedX, adjustedY);
    });
  }

  $(document).on('mousemove', handleMouseMove);

  const fadeElements = $('.Title-anim, .about, .content, .cards');
  fadeElements.on({
    'mouseenter': function () {
      cursorDot.stop().fadeTo(200, 0);
    },
    'mouseleave': function () {
      cursorDot.stop().fadeTo(200, 1);
    }
  });
});

I’m particularly interested in improving the animation smoothness and reducing any potential lag. Any suggestions or optimizations would be greatly appreciated. Thanks!

Not getting the Post Data in PostMan

I have made a router, Database , Model, and Mongoose for a task manager where I have to post multiple tasks and be able to read all of them on PostMan as Well.

The Server and the DataBase is Connected but at the PostMan I keep getting the error that “Cannot POST /task”

I would like to know what exactly is the issue and how do I resolve it?

(simple, but strange) Problem looping through a big JSON data file JS, Python [duplicate]

Context

Hello, I have a JSON file with a list of objects similar to this:

[{
"Codigo":"01",
"Descricao":"Animais vivos.",
"Data_Inicio":"01/04/2022",
"Data_Fim":"31/12/9999",
"Tipo_Ato":"Res Camex",
"Numero_Ato":"272",
"Ano_Ato":"2021"
},
{
"Codigo":"0102.31",
"Descricao":"-- Reprodutores de raça pura",
"Data_Inicio":"01/04/2022",
"Data_Fim":"31/12/9999",
"Tipo_Ato":"Res Camex",
"Numero_Ato":"272",
"Ano_Ato":"2021"
}, .....]

the list above have 15075 objects. I’m making a script that check if “Codigo” have more than 6 caracteres, if yes, it will pop it out of the list.

Problem

I’ve tried to make it using javaScript and python, and have the same problem in both languages. when executing the following code:

javaScript

for(var i= 0; i <Nomenclaturas.length; i++){
   if(Nomenclaturas[i].Codigo.length>6){
      Nomenclaturas.splice(i,1)
   }
}
console.log(Nomenclaturas.length)
//result = 8180

the code in JavaScript doesn’t make it’s job, because some objects in my list with Codigo.length>6 aren’t removed. The strange part is if I repeat the same code chunk above multiple times, it works:

for(var i= 0; i <Nomenclaturas.length; i++){
   if(Nomenclaturas[i].Codigo.length>6){
      Nomenclaturas.splice(i,1)
   }
}
console.log(Nomenclaturas.length)
//result = 8180
for(var i= 0; i <Nomenclaturas.length; i++){
   if(Nomenclaturas[i].Codigo.length>6){
      Nomenclaturas.splice(i,1)
   }
}
console.log(Nomenclaturas.length)
//result = 4646

for(var i= 0; i <Nomenclaturas.length; i++){
   if(Nomenclaturas[i].Codigo.length>6){
      Nomenclaturas.splice(i,1)
   }
}
console.log(Nomenclaturas.length)
//result = 2984

when I repeat the code chunk 7 times, it do what it suppose to do. I’ve tried the same script in python:

for i, nome in enumerate(nomeclaturas):
    if(len(nome['Codigo'])>6):
        del nomeclaturas[i]
print(len(nomeclaturas))
#result = 8180

And I’ve the same problem, it doesn’t work by complete, and It works when I repeat the code “for” code chunk.

my operational system:
Windows 11 home 64-bit (10.0, build 22621)

you can download this JSON here:
https://portalunico.siscomex.gov.br/classif/#/nomenclatura/tabela?perfil=publico

Selection “tabela vigente” and “JSON”

How to convert lunar calendar to solar calendar in javascript

I want to convert a chineese/corean lunar date calendar exclusively to the solar calendar. How can I achieve this? i tried to use some libraries like this: https://www.npmjs.com/package/lunar-date-calculator

but when i input 15/02/2023 in format GG/MM/YYYY the result is only one. if you use this calculator the result for the same date are two. https://datecalculator.kr/%EC%96%91%EB%A0%A5-%EC%9D%8C%EB%A0%A5-%EA%B3%84%EC%82%B0%EA%B8%B0/

Getting 500 internal server error but data is getting printed in console

I have created the api to fetch data from big-query into my nextjs 13 admin dashboard
while testing the data, I am getting 500 internal server error but data is getting printed in console

api/bigQuery/route.js

import { BigQuery } from "@google-cloud/bigquery";


//! Initialize BigQuery client
const bigquery = new BigQuery({
  projectId: process.env.GCP_PROJECT_ID,
  keyFilename: process.env.GCP_PRIVATE_KEY,
});

export const GET = async () => {
  try {
    console.log("Fetching data from BigQuery...");

    const metrics = [
      // ! Customer Demographics Dashboard
      {
        name: "Customer's Age Group",
        query: `
          SELECT 
            CASE 
              WHEN CustomerAge BETWEEN 1 AND 18 THEN '1-18'
              WHEN CustomerAge BETWEEN 19 AND 27 THEN '19-27'
              WHEN CustomerAge BETWEEN 28 AND 40 THEN '28-40'
              WHEN CustomerAge BETWEEN 41 AND 54 THEN '41-54'
              WHEN CustomerAge BETWEEN 55 AND 67 THEN '55-67'
              ELSE '68+'
            END AS CustomerAgeRange,
            COUNT(*) AS CustomerCount
          FROM NewMVP.all
          
          GROUP BY CustomerAgeRange
          ORDER BY CustomerAgeRange;
        `,
      },
      {
        name: "Customer's Gender",
        query: `
          SELECT 
            Gender as CustomerGender, 
            COUNT(*) AS CustomerCount
          FROM goldengcsrec.custdatarec
          GROUP BY CustomerGender
          ORDER BY CustomerGender
        `,
      },
      {
        name: "Customer's Location",
        query: `
        SELECT 
        CustomerLocation,
        COUNT(*) AS CustomerCount
        FROM NewMVP.Customer
        GROUP BY CustomerLocation
        ORDER BY CustomerCount DESC
        LIMIT 5;
        `,
      },
      // { name: "Customer Income Level",
      //  query:``,
      //  }

      // ! Customer Behavior Dashboard
      // {
      //   name: "Foot Traffic Count - Monthly",
      //   query: `
      //     SELECT
      //       DATE_TRUNC(LastVisitDate, MONTH) AS MonthStart,
      //       COUNT(*) AS FootTrafficCount
      //     FROM NewMVP.Customer
      //     GROUP BY MonthStart
      //     ORDER BY MonthStart;
      //   `,
      // },
      {
        name: "Foot Traffic by Time(days of week)",
        query: `
        SELECT 
          EXTRACT(DAYOFWEEK FROM LastVisitDate) AS DayOfWeek,
          EXTRACT(HOUR FROM LastVisitTime) AS HourOfDay,
          COUNT(*) AS FootTrafficCount
        FROM NewMVP.CustomerData
        GROUP BY DayOfWeek, HourOfDay
        ORDER BY DayOfWeek, HourOfDay;
      `,
      },
      {
        name: "Average Spending",
        query: `
          SELECT 
            LoyaltyPointsMemberStatus,
            AVG(AmountPaid) AS AvgSpendPerVisit
          FROM NewMVP.Customer
          GROUP BY LoyaltyPointsMemberStatus;
        `,
      },
      //! Customer Reviews Dashboard
      {
        name: "Most Mentioned Dishes",
        query: `
          SELECT 
            MenuItemName,
            COUNT(*) AS MentionFrequency
          FROM NewMVP.Customer
          GROUP BY MenuItemName
          ORDER BY MentionFrequency DESC
          LIMIT 7;
        `,
      },
      {
        name: "Review Trends",
        query: `
          SELECT 
          SUBSTR(CommentDate, 6, 2) AS Month,
          COUNT(*) AS ReviewCount
          FROM NewMVP.Customer
          GROUP BY Month
          ORDER BY Month;
        `,
      },

      // !Loyalty Program Dashoard
      {
        name: "Number of Loyalty Members",
        query: `
          SELECT 
          LoyaltyPointsMemberStatus,
          COUNT(*) AS TotalCustomer
          FROM NewMVP.Customer
          GROUP BY LoyaltyPointsMemberStatus
          ORDER BY LoyaltyPointsMemberStatus;
        `,
      },
      {
        name: "Average Spend per Member",
        query: `
          SELECT 
            LoyaltyPointsMemberStatus,
            AVG(AmountPaid) AS AvgSpendPerVisit
          FROM NewMVP.Customer
          GROUP BY LoyaltyPointsMemberStatus;
        `,
      },
      {
        name: "Loyalty Program Engagement",
        query: `
            SELECT 
            LoyaltyPointsMemberStatus,
              SUM(LoyaltyPointsEarned) AS TotalPointsEarned
            FROM NewMVP.Customer
            GROUP BY LoyaltyPointsMemberStatus;
          `,
      },

      // ! Customer Feedback Dashboard
      // {
      //   name: "Survey Result",
      //   query: `
      //       SELECT
      //       LoyaltyPointsMemberStatus,
      //         SUM(LoyaltyPointsEarned) AS TotalPointsEarned
      //       FROM NewMVP.Customer
      //       GROUP BY LoyaltyPointsMemberStatus;
      //     `,
      // },
      // {
      //   name: "Improvment Area",
      //   query: `
      //       SELECT
      //       LoyaltyPointsMemberStatus,
      //         SUM(LoyaltyPointsEarned) AS TotalPointsEarned
      //       FROM NewMVP.Customer
      //       GROUP BY LoyaltyPointsMemberStatus;
      //     `,
      // },
      // {
      //   name: "Action Plan",
      //   query: `
      //       SELECT
      //       LoyaltyPointsMemberStatus,
      //         SUM(LoyaltyPointsEarned) AS TotalPointsEarned
      //       FROM NewMVP.Customer
      //       GROUP BY LoyaltyPointsMemberStatus;
      //     `,
      // },
      // {
      //   name: "Dine-In Experience Trends",
      //   query: `
      //   SELECT
      //     EXTRACT(YEAR FROM LastVisitDate ) AS Year,
      //     EXTRACT(MONTH FROM LastVisitDate ) AS Month,
      //     AVG(Rating) AS AverageSatisfactionScore
      //   FROM NewMVP.Customer
      //   GROUP BY Year, Month
      //   ORDER BY Year, Month;
      //     `,
      // },

      // ! Customer Rention Dashboard
    ];

    const dataPromises = metrics.map(async (metric) => {
      try {
        const [rows] = await bigquery.query({ query: metric.query });
        console.log(`Fetched data for ${metric.name}:`, rows);
        return { [metric.name]: rows };
      } catch (error) {
        console.error(`Error fetching ${metric.name} data:`, error);
        throw error;
      }
    });

    const results = await Promise.all(dataPromises);
    const responseData = results.reduce(
      (acc, result) => ({ ...acc, ...result }),
      {}
    );

    return {
      statusCode: 200,
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(responseData),
    };
  } catch (error) {
    console.error("Error fetching data:", error);
    return {
      statusCode: 500,
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ error: "Error fetching data from BigQuery" }),
    };
  }
};

I am attaching the screen-shot of the consol-log

Due to the 500 error I’m unable to get the in client-side

this is my client-side code

"use client";
import React, { useEffect, useState } from "react";
import { useTheme } from "@mui/material/styles";
import dynamic from "next/dynamic";
import BaseCard from "../../../shared/DashboardCard";
const Chart = dynamic(() => import("react-apexcharts"), { ssr: false });

const Gender = () => {
  const theme = useTheme();
  const primary = theme.palette.warning.dark;
  const secondary = theme.palette.secondary.main;
  const [loading, setLoading] = useState(true);
  const [customerGenderData, setCustomerGenderData] = useState([]);

  useEffect(() => {
    fetch("/api/bigQuery")
      .then((response) => response.json())
      .then((data) => {
        console.log("Fetched data:", data);
        const genderData = data["Customer's Gender"];
        setCustomerGenderData(genderData);
        setLoading(false);
      })
      .catch((error) => {
        console.error("Error fetching data:", error);
        setLoading(false);
      });
  }, []);

  const optionssalesoverview = {
    grid: {
      show: true,
      position: "back",
      padding: {
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
      },
    },
    plotOptions: {
      bar: {
        horizontal: false,
        columnWidth: "55%",
        endingShape: "rounded",
        distributed: true,
      },
    },
    fill: {
      type: "solid",
      opacity: 1,
    },
    colors: [
      "#003049",
      "#d62828",
      "#f77f00",
      "#fcbf49",
      "#eae2b7",
      "#B38CB4",
      "#5D2A42",
    ],
    chart: {
      type: "bar",
      offsetX: -15,
      toolbar: {
        show: false,
      },
      fontFamily: "inherit",
    },
    dataLabels: {
      enabled: true,
    },
    markers: {
      size: 0,
    },
    legend: {
      show: false,
    },
    xaxis: {
      type: "category",
      categories: customerGenderData.map((entry) => entry.CustomerGender),
      title: {
        text: "Gender Category",
        style: {
          cssClass: "grey--text lighten-2--text fill-color",
          fontSize: "16px",
          color: "#000",
        },
      },

      labels: {
        style: {
          cssClass: "grey--text lighten-2--text fill-color",
          fontSize: "16px",
        },
      },
    },
    yaxis: {
      show: true,
      tickAmount: 3,
      title: {
        text: "No. of Customer",
        style: {
          cssClass: "grey--text lighten-2--text fill-color",
          fontSize: "16px",
          color: "#000",
        },
      },
      labels: {
        style: {
          cssClass: "grey--text lighten-2--text fill-color",
          fontSize: "16px",
        },
      },
    },
    stroke: {
      show: true,
      width: 5,
      lineCap: "butt",
      colors: ["transparent"],
    },
    tooltip: {
      theme: "dark",
    },
  };
  return (
    <BaseCard title="Gender Distribution">
      {loading ? (
        <p>Loading...</p>
      ) : (
        <Chart
          options={optionssalesoverview}
          series={[
            { data: customerGenderData.map((entry) => entry.CustomerCount) },
          ]}
          type="bar"
          height="370px"
        />
      )}
    </BaseCard>
  );
};
export default Gender;

What I should change in api to avoid 500 error

I have nextjs 13 admin dashboard with 40+ and 160+ charts, I have created an API to fetch required data for the chart which is stored in Big-Query. Currently I’m expecting to get 200 status code but I’m getting 500 internal server error code but data is getting printed in console

Encode audio data to string (Flask) and decode it (Javascript)

I have a Python Flask app with the method shown below. In the method I’m synthesizing voice from text using Azure text to speech.

@app.route("/retrieve_speech", methods=['POST'])
def retrieve_speech():
    text= request.form.get('text')
    start = time.time()
    speech_key = "my key"
    speech_region = "my region"
    speech_config = speechsdk.SpeechConfig(subscription=speech_key, region=speech_region)
    speech_config.endpoint_id = "my endpoint"
    speech_config.speech_synthesis_voice_name = "voice name"
    speech_config.set_speech_synthesis_output_format(
        speechsdk.SpeechSynthesisOutputFormat.Audio24Khz160KBitRateMonoMp3)
    synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=None)

    result = synthesizer.speak_text_async(text=text).get()

    if result.reason == speechsdk.ResultReason.SynthesizingAudioCompleted:
        # Convert to wav
        audio = AudioSegment.from_file(io.BytesIO(result.audio_data))
        duration = audio.duration_seconds
        data = io.BytesIO()
        audio.export(data, format='wav')
        data.seek(0)

        # Convert binary data to base64 string
        data = base64.b64encode(data.read()).decode('utf-8')

        speech_timing = time.time() - start
    elif result.reason == speechsdk.ResultReason.Canceled:
        cancellation_details = result.cancellation_details
        if cancellation_details.reason == speechsdk.CancellationReason.Error:
            logging.error("Azure speech synthesis failed: {}".format(cancellation_details.error_details))

    return jsonify(audio_data=data, speech_timing=str(speech_timing), other="other strings")

I’m using the Flask method in my frontend (webpage) using Javascript as follows:

    $.post("/retrieve_speech", { text: "This is a test" }).done(function (data) {
        var audio_data= data.audio_data;
        var speech_timing = data.speech_timing;
        var other = data.other;

        // Decode base64 string to binary
        var binaryData = atob(audioData);

        // Create an array of 8-bit unsigned integers
        var byteArray = new Uint8Array(binaryData.length);
        for(var i = 0; i < binaryData.length; i++) {
            byteArray[i] = binaryData.charCodeAt(i);
        }

        // Create a blob object from the byte array
        var blob = new Blob([byteArray], {type: 'audio/wav'});

        // Create a URL for the blob object
        var url = URL.createObjectURL(blob);

        // Play the audio
        var audio = new Audio(url);
        audio.play();

The problem now is that the audio is not playing. In addition in the Flask app I’m getting the following message: Numba: Attempted to fork from a non-main thread, the TBB library may be in an invalid state in the child process.

Synthesizing the speech works, so the problem must be the conversion to wav or to string in the Flask app and/or the decoding of the string in Javascript.

Is something wrong with my code?

How to pass server properties to a route.js api using nextjs app router

I have a nextjs app with a custom server.js that reads some config settings from a config file on startup. I would like to pass some of these properties along with a session key that gets read on startup to a local api that can then be used from one of the client pages. I’m using the app router and have the api route.js file working but I can’t figure out the correct way of passing these properties over from the server to the route.js file. I tried some static properties on a config helper file but these were undefined when I tried to read them from the route.js file.

I tried some static properties on a config helper file but these were undefined when I tried to read them from the route.js file.

Is there a way to paint this image and then gets unblurry?

I am trying to create a website animation like this in the video but something is wrong.
I could only make it so the image gets clear only where the mouse pointer is located.

HTML CODE

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="styles.css">
    <title>Dynamic Unblur with Color</title>
</head>
<body>
    <div class="background-container">
        <div class="blurred-image"></div>
        <div class="clear-image"></div>
    </div>
    <script src="script.js"></script>
</body>
</html>

CSS CODE


body {
    cursor: url('C'), auto;
}
 
.background-container {
    position: relative;
    width: 100%;
    height: 100vh;
    overflow: hidden;
}
 
.blurred-image {
    width: 100%;
    height: 100%;
    background: url('https://i.ibb.co/4WfHR0L/1-background-is-blurred.png') center/cover no-repeat;
    filter: blur(10px);
    transition: filter 0.5s ease;
}
 
.clear-image {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: url('https://i.ibb.co/Hr2nrNH/2-then-with-mouse-background-is-clear.png') center/cover no-repeat;
    clip-path: circle(0% at 50% 50%);
    transition: clip-path 0.5s ease, filter 0.5s ease; /* Προσαρμοσμένος χρόνος μετάβασης */
    filter: blur(10px); /* Αρχική θολούρα */
}
 
.clear-image::before {
    content: '';
    position: absolute;
    top: -50%;
    left: -50%;
    width: 200%;
    height: 200%;
    background-color: rgba(0, 128, 255, 0.5);
    clip-path: circle(5% at 50% 50%); /* Μικρότερος κύκλος */
    transition: clip-path 0.5s ease; /* Προσαρμοσμένος χρόνος μετάβασης */
}
 
.pointer {
    position: absolute;
    top: var(--mouseY, 50%);
    left: var(--mouseX, 50%);
    transform: translate(-50%, -50%);
    width: 20px;
    height: 20px;
    background: url('pointer.png') center/cover no-repeat;
    display: none;
}
 
.background-container:hover .blurred-image {
    filter: blur(0);
}
 
.background-container:hover .clear-image {
    clip-path: circle(20% at var(--mouseX, 50%) var(--mouseY, 50%)); /* Μεγαλύτερος κύκλος για καθαρή περιοχή */
    filter: blur(0); /* Καθαρισμός της εικόνας */
}
 
.background-container:hover .clear-image::before {
    clip-path: circle(0% at var(--mouseX, 50%) var(--mouseY, 50%));
}
 
.background-container:hover .pointer {
    display: block;
}


JS CODE

const backgroundContainer = document.querySelector('.background-container');
const clearImage = document.querySelector('.clear-image');
 
let mouseOverCount = 0;
let isCleared = false;
 
backgroundContainer.addEventListener('mouseover', () => {
    mouseOverCount++;
 
    if (mouseOverCount >= 3 && !isCleared) {
        clearImage.classList.add('cleared');
        isCleared = true;
        mouseOverCount = 0;
 
        setTimeout(() => {
            clearImage.classList.remove('cleared');
            isCleared = false;
        }, 2000); // Reset after 2 seconds (adjust as needed)
    }
});
 
backgroundContainer.addEventListener('mousemove', (event) => {
    const mouseX = (event.clientX / window.innerWidth) * 100 + '%';
    const mouseY = (event.clientY / window.innerHeight) * 100 + '%';
 
    clearImage.style.setProperty('--mouseX', mouseX);
    clearImage.style.setProperty('--mouseY', mouseY);
});

The image should be blurry in first place and when the user paint over the image should get clear whatch the video of the animation

stripe error cannot read properties of undefined (reading ‘brand’)

EDIT

What I have noticed is when I put card instead of payment here – elements.create(‘payment’,… it works, but I need it as payment type.


I have a stripe js code. I think i have setup everything correctly, but for some reason when I try to submit card I get this error – TypeError’, message: “Cannot read properties of undefined (reading ‘brand’)”, stack: ‘TypeError: Cannot read properties of undefined (re…ller-5bcd098058bc88e780b07fdc7a7c5c39.js:1:675761’}

                const stripe = Stripe('pk_test_....');

                const options = {
                currency: 'usd',
                appearance: {/*...*/},
                clientSecret: '<?php echo esc_js($client_secret); ?>',
                };
                
                elements = stripe.elements(options);

                

                   
                
                    const paymentElement = elements.create('payment', {
                        fields: {
                            billingDetails: {
                                address: {
                                    country: 'never',
                                }
                            }
                        }
                    });
                
                    paymentElement.mount('#stripe_payment');

                
                
                var form = document.getElementById('stripe_form_checkout');
                form.addEventListener('submit', function(event) {
                  event.preventDefault();
                
                  stripe.createToken(paymentElement).then(function(result) {
                    if (result.error) {
                      alert("failure")
                    } else {
                      alert("success")
                    }
                  });
                });

How to prevent text selection while using VueJS?

If I have a component that renders some text and make an initial click somewhere on the text (for example at the beginning) and then the second time a shift-click on another part of the text (for example at the end) the text between those 2 click positions is selected.

How can I prevent this from happening using a pure VueJS solution if possible?

Asynchronous Chrome History Search in a Loop – How to ensure sendResponse waits for all operations to complete?

I am developing a Chrome extension, and I’m currently working on a feature to stop saving history within specific time intervals. The core functionality involves using chrome.history.search within a loop to fetch history items for each interval.

The issue I’m facing is that the sendResponse function is being called before all the history items are processed. This premature invocation is causing incomplete data to be sent in the response.

The snippet of the code is given below

else if (message.type === "stopSavingHistory") {
    // Stop history saving in the background script
    let history = [];
    console.log("Received message to stop saving history", timeInterval);
    for (let i = 0; i < timeInterval.length; i++) {
      let hist = [];
      let x = Math.floor(timeInterval[i].startTime.getTime());
      let y = Math.floor(timeInterval[i].endTime.getTime());
      console.log("x", x);
      console.log("y", y);
      chrome.history.search(
        {
          text: "",
          startTime: x,
          endTime: y,
        },
        function (historyItems) {
          chrome.storage.local.set({ history: historyItems });
          console.log("--->", historyItems);
          hist = [...historyItems];
          sendResponse({
            message: "History saving stopped",
            data: historyItems,
          });
        }
      );
    }
  }

When I am executing this code, I’m getting this error ” “index.html:1 Unchecked runtime.lastError: The message port closed before a response was received.”

If I change the data to be a simple text message like “Hello” then it is working as expected. I asked the chatgpt for the solution it gave me this result

else if (message.type === "stopSavingHistory") {
    // Stop history saving in the background script
    let historyPromises = [];
    console.log("Received message to stop saving history", timeInterval);
    
    for (let i = 0; i < timeInterval.length; i++) {
        let hist = [];
        let x = Math.floor(timeInterval[i].startTime.getTime());
        let y = Math.floor(timeInterval[i].endTime.getTime());
        console.log("x", x);
        console.log("y", y);

        // Wrap the asynchronous operation in a Promise
        let historyPromise = new Promise(resolve => {
            chrome.history.search(
                {
                    text: "",
                    startTime: x,
                    endTime: y,
                },
                function (historyItems) {
                    chrome.storage.local.set({ history: historyItems });
                    console.log("--->", historyItems);
                    hist = [...historyItems];
                    resolve(historyItems);
                }
            );
        });

        historyPromises.push(historyPromise);
    }

    // Wait for all Promises to resolve before calling sendResponse
    Promise.all(historyPromises)
        .then(historyItemsArray => {
            let allHistoryItems = [].concat(...historyItemsArray);
            sendResponse({
                message: "History saving stopped",
                data: allHistoryItems,
            });
        })
        .catch(error => {
            console.error("Error while fetching history:", error);
            sendResponse({
                message: "Error occurred during history retrieval",
                error: error,
            });
        });
}

But it is still producing the same error. Am I missing something? This is my first time building a chrome extension. I’m passing this response from background.js to popup.js. Can please someone help?

How to get select option and put them in an array?, playwright + JavaScript

I am trying to use Playwright to locate and extract all options/text from the third HTML element and push it to an array? I have tried different alternatives, page.locate(), page.$$eval() and page.evaluate(). My goal is to loop over the options in the third select element and get the data from each option.

    "playwright": "^1.40.1"
const { chromium } = require("playwright");

const url = `<html lang="es">

<head>
    <meta charset="UTF-8">
    <link rel="icon" type="image/png" sizes="96x96" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>

<body>
    <div id="app" data-v-app="">
        <div class="f-container fixed-hf">
            <header>
                HEADER
            </header>
            <main class="flex flex-col main mx-0 sm:mx-32">
                <div class="w-full">
                    <div class="flex justify-end p-1 border border-slate-300 shadow-lg overflow-auto">
                        HEADER BUTTONS
                    </div>
                </div>
                <div class="flex flex-wrap h-full">
                    <div class="w-full md:w-3/12 border-x-2 border-gray-300 bg-slate-100">
                        <div class="flex flex-col p-2 m-1 border border-slate-300 shadow-lg">
                            <div class="w-full sm:w-12/12 px-1">
                                <h2>Other links</h2>
                            </div>
                        </div>
                        <div class="flex flex-col p-2 m-2">
                            <div>
                                <label for="first_select">First Select:</label>
                                <select class="select">
                                    <option value="[object Object]">One</option>
                                    <option value="[object Object]">Two</option>
                                    <option value="[object Object]">Three</option>
                                    <option value="[object Object]">Fourth</option>
                                    <option value="[object Object]">Five</option>
                                    <option value="[object Object]">Six</option>
                                    <option value="[object Object]">Seven</option>
                                </select>
                            </div>
                            <div class="w-full">
                                <label for="second_select">Second Select:</label>
                                <select class="select">
                                    <option value="[object Object]">A</option>
                                    <option value="[object Object]">B</option>
                                    <option value="[object Object]">C</option>
                                    <option value="[object Object]">D</option>
                                    <option value="[object Object]">E</option>
                                    <option value="[object Object]">F</option>
                                    <option value="[object Object]">G</option>
                                    <option value="[object Object]">H</option>
                                    <option value="[object Object]">Y</option>
                                    <option value="[object Object]">J</option>
                                    <option value="[object Object]">K</option>
                                    <option value="[object Object]">L</option>
                                    <option value="[object Object]">M</option>
                                    <option value="[object Object]">N</option>
                                    <option value="[object Object]">O</option>
                                    <option value="[object Object]">P</option>
                                    <option value="[object Object]">Q</option>
                                    <option value="[object Object]">R</option>
                                </select>
                            </div>
                            <div class="w-full">
                                <label for="third_select">Third Select:</label>
                                <select class="select">
                                    <option value="[object Object]">11</option>
                                    <option value="[object Object]">22</option>
                                    <option value="[object Object]">33</option>
                                    <option value="[object Object]">44</option>
                                    <option value="[object Object]">45</option>
                                    <option value="[object Object]">46</option>
                                    <option value="[object Object]">47</option>
                                    <option value="[object Object]">48</option>
                                    <option value="[object Object]">49</option>
                                    <option value="[object Object]">50</option>
                                    <option value="[object Object]">51</option>
                                    <option value="[object Object]">52</option>
                                    <option value="[object Object]">53</option>
                                    <option value="[object Object]">54</option>
                                    <option value="[object Object]">55</option>
                                    <option value="[object Object]">56</option>
                                    <option value="[object Object]">57</option>
                                    <option value="[object Object]">58</option>
                                    <option value="[object Object]">59</option>
                                    <option value="[object Object]">60</option>
                                </select></div>
                            </div>
                    </div>
                    <div class="w-full md:w-9/12">
                        <div>
                            <div class="flex flex-col p-2 border border-slate-300 m-1 shadow-lg">
                                <div>
                                    <div class="w-full">
                                        <div class="row">
                                            <div>
                                                <div class="w-full">
                                                    <div class="flex flex-row justify-between">
                                                        <div class="w-3/4">
                                                            <div class="p-6"><!---->
                                                                <div>
                                                                    <div class="w-full">
                                                                        <h1 class="titulo">Data
                                                                            Experimental</h1>
                                                                    </div>
                                                                    <div class="row"><!---->
                                                                        <h2 class="sub-titulo">Total uno</h2>
                                                                        <h3 class="detalles"></h3>
                                                                        <p></p>
                                                                    </div>
                                                                    <div class="relative inline-block text-left float-left">
                                                                        <div></div>
                                                                    </div>
                                                                </div>
                                                            </div>
                                                        </div>
                                                        <div class="w-1/6">
                                                            <div class="mb-4"></div>
                                                        </div>
                                                    </div>
                                                </div>
                                                <div class="w-full">
                                                    <table class="table">
                                                        <div>HERE COME THE DINAMIC DATA</div>
                                                    </table>
                                                    
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="w-full"></div>
                                    <div class="w-full"></div>
                                    <div class="w-full"></div>
                                </div>
                            </div>
                            <div class="flex flex-wrap justify-center pt-8 mt-8">
                                <div class="flex flex-wrap w-full justify-center float">
                                    <div></div>
                                    <div></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </main>
            <footer class="footer">
                <div class="flex justify-center h-14 pt-3">
                    <p>Footer</p>
                </div>
            </footer>
        </div>
    </div>
</body>

</html>`;

(async () => {
  const browser = await chromium.launch({ headless: false });
  const context = await browser.newContext();
  const page = await context.newPage();
  await page.goto(url);

  const locatorGetBy = await page.getByRole("select", { class: "select" });

  if (locatorGetBy) {
    console.log("The locator is here!");
  }

  console.log("I do get something here?", locatorGetBy.allTextContents());

  const locator = await page.locator(
    "//*[@id='app']/div/main/div[2]/div[1]/div[2]/div[5]/select/option/option/pico"
  );
  const elementsCount = await locator;
  console.log("There are:", elementsCount.count());

  /*   let selectComunas = await page
    .locator("//*[@id='app']/div/main/div[2]/div[1]/div[2]/div[5]/select")
    .selectOption({ index: 50 }); */



  await browser.close();
})();

About switching of language in React

I’m using a react dashboard and I wish to translate the app using i18next, I’m very beginner in React, I have a button to switch language like this :

                    <button className={`${styles.control} h5`} onClick={toggleDirection}>
                    <i className="icon icon-book-regular"/>
                    {direction === 'ltr' ? 'ENGLISH' : 'ARABIC'}
                   </button>

I wish to change the button without changing the style and button and doing something like that:

      import { Suspense, useState } from 'react';
      import { useTranslation } from 'react-i18next';

      const locales = {
      en: { title: 'English' },
      es: { title: 'Arabic' },
      };

   const { t, i18n } = useTranslation();
   <ul>
    {Object.keys(locales).map((locale) => (
      <li key={locale}><button style={{ fontWeight: i18n.resolvedLanguage === locale ? 'bold' : 'normal' }} type="submit" onClick={() => i18n.changeLanguage(locale)}>
        {locales[locale].title}
      </button></li>
    ))}
  </ul>

How to find out the scroll direction when you click on an anchor

I have a header that hides when scrolling down and shows when scrolling up. I also have a sticky banner that changes its top depending on the scroll so as not to interfere with the header. I have sticky anchors that, when clicked, need to be scrolled to sections. The problem is that if, when clicked, the page scrolls up, both the header and the banner are visible, but if it scrolls down, then only the banner because the header is hidden. Depending on the scroll direction, I need to add an offset so that the header or banner does not overlap the beginning of the section. How can I determine the scroll direction when clicked in order to add a different offset?

  document.querySelectorAll('#page-list a[href^="#"]').forEach((anchor) => {
    anchor.addEventListener("click", function (e) {
      e.preventDefault();

      const targetElement = document.querySelector(this.getAttribute("href"));
      const headerHeight = document.querySelector("header").offsetHeight;
      const bannerHeight = document.querySelector(
        ".compare-form__sticky"
      ).offsetHeight;

      if (targetElement) {
        const elementPosition = targetElement.getBoundingClientRect().top;
        const offset = -headerHeight - bannerHeight - 17;
        console.log(offset);
        const offsetPosition = elementPosition + window.scrollY + offset;

        window.scrollTo({
          top: offsetPosition,
          behavior: "smooth",
        });
      }
    });
  });