Error message: Property ‘onCommentCreate’ does not exist on type ‘IFrame’.ts(2339)

I’m trying to create a trigger when a new comment is posted in Wix Comments widget.
This is the code in the wix comments widget page (Frontend):

$w("#wixComments1").onCommentCreate((widgetComment) => {
    // Log the newly created comment to the console
    console.log("New comment created:", widgetComment);
    // You can add additional logic here to process the comment
});

The Wix IDE throws this error: “Property ‘onCommentCreate’ does not exist on type ‘IFrame’.ts(2339)”

Can anyone help me on this, i’m new to Velo…

unexpected end of archive error when trying to open a Zip file downloaded via javascript

I’m trying to download a ZIP file from a backend API that returns the ZIP binary as a string.

If I do this:
curl --location 'https://backend-endpoint.com/get-file' >> test.zip it creates a ZIP file containing a couple of files that I can extract and open correctly.

On the frontend side I have a button that, if clicked, calls the following code that should download the ZIP file after the backend API call:

const convertBinaryToBlob = (binary: string, contentType: string): Blob => {
    // Convert the binary string to a byte array
    const binaryLen = binary.length;
    const bytes = new Uint8Array(binaryLen);
    for (let i = 0; i < binaryLen; i++) {
      bytes[i] = binary.charCodeAt(i);
    }

    const blob = new Blob([bytes], { type: contentType });
    return blob;
};

clientAPI.getFile().then((resp) => {
    if (resp.status === 200) {
        let blobContent = convertBinaryToBlob(resp.data, 'application/zip');
        const href = URL.createObjectURL(blobContent);
        const link = document.createElement('a');
        link.href = href;
        link.setAttribute('download', 'test.zip');
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        URL.revokeObjectURL(href);
    }
});

When I click the button a ZIP file is downloaded but it seems corrupt because If I try opening it I get the following error: unexpected end of archive

What am i doing wrong?

How to make any native know to use document.currentScript.src or import.meta.url

I have no control how a 3rd party loads my scipt.

Can be <script type="module" src="myscript.js"> or <script src="myscript.js">

When not loaded as “module” the code inside my script always errors with:

Uncaught SyntaxError: Cannot use ‘import.meta’ outside a module

This SO answer “Uncaught SyntaxError: Cannot use import statement outside a module” when importing ECMAScript 6
is not an answer for native/vanilla JavaScript without bundling.

Is it possible at all to test for “module” inside a non-module script?

A simple if does not work:

    let myURL = "";
    if (document.currentScript) {
        myURL = document.currentScript.src;
    } else {
        myURL = import.meta.url;
    }

Try-Catch does not work:

    let myURL = "";
    try {
        myURL = import.meta.url;
    } catch (e) {
        if (document.currentScript) myURL = document.currentScript.src;
    }

You-know-who and You-know-Elon-who come up with variations of above code that do not work, causing the error

webpack-cli TypeError: Cannot read properties of undefined (reading ‘getArguments’)

I am trying to deploy my application and getting this error. Locally it is working perfectly fine here is the complete stack trace:

    2025-02-20T09:20:27.0519522Z > [email protected] build
2025-02-20T09:20:27.0520079Z > npm run migrate && webpack --config webpack.prod.js
2025-02-20T09:20:27.0521155Z 
2025-02-20T09:20:29.0825668Z 
2025-02-20T09:20:29.0838195Z > [email protected] migrate
2025-02-20T09:20:29.0838877Z > npx sequelize-cli db:migrate
2025-02-20T09:20:29.0839675Z 
2025-02-20T09:20:36.2886604Z 
2025-02-20T09:20:36.2887992Z [4mSequelize CLI [Node: 16.18.1, CLI: 6.6.2, ORM: 6.37.5][24m
2025-02-20T09:20:36.2888730Z 
2025-02-20T09:20:36.3267065Z Loaded configuration file "server/db/config.json".
2025-02-20T09:20:36.3267758Z Using environment "production".
2025-02-20T09:20:40.1777294Z No migrations were executed, database schema was already up to date.
2025-02-20T09:20:42.4559654Z [webpack-cli] TypeError: Cannot read properties of undefined (reading 'getArguments')
2025-02-20T09:20:42.4560664Z     at WebpackCLI.getBuiltInOptions (/var/www/html/litpath/litpath-dev/code/node_modules/webpack-cli/lib/webpack-cli.js:831:77)
2025-02-20T09:20:42.4562402Z     at makeCommand.options.entry (/var/www/html/litpath/litpath-dev/code/node_modules/webpack-cli/lib/webpack-cli.js:939:33)
2025-02-20T09:20:42.4563728Z     at async WebpackCLI.makeCommand (/var/www/html/litpath/litpath-dev/code/node_modules/webpack-cli/lib/webpack-cli.js:443:31)
2025-02-20T09:20:42.4566602Z     at async loadCommandByName (/var/www/html/litpath/litpath-dev/code/node_modules/webpack-cli/lib/webpack-cli.js:937:17)
2025-02-20T09:20:42.4571521Z     at async Command.<anonymous> (/var/www/html/litpath/litpath-dev/code/node_modules/webpack-cli/lib/webpack-cli.js:1336:17)
2025-02-20T09:20:42.4572305Z     at async Command.parseAsync (/var/www/html/litpath/litpath-dev/code/node_modules/webpack-cli/node_modules/commander/lib/command.js:935:5)
2025-02-20T09:20:42.4573019Z     at async WebpackCLI.run (/var/www/html/litpath/litpath-dev/code/node_modules/webpack-cli/lib/webpack-cli.js:1360:9)
2025-02-20T09:20:42.4574822Z     at async runCLI (/var/www/html/litpath/litpath-dev/code/node_modules/webpack-cli/lib/bootstrap.js:9:9)

My dependencies: (I am using node 16.x on my deployment server and locally it’s 20.x)

"webpack": "^5.92.1",
  "webpack-cli": "^5.1.4",

with this configuration my build is successfull but when running application on startup it failed.

My webpack.prod.js:

const merge = require('webpack-merge')
const webpack = require('webpack')
const TerserPlugin = require('terser-webpack-plugin')
const BrotliPlugin = require('brotli-webpack-plugin')
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')
const common = require('./webpack.common')

module.exports = () => {
  return merge(common, {
    optimization: {
      splitChunks: {
        chunks: 'all',
      },
      minimize: true,
      minimizer: [new TerserPlugin()],
    },
    devtool: 'source-map',
    mode: 'production',
    // https://webpack.js.org/plugins/define-plugin/
    // babel-minify-webpack look
    plugins: [
      new webpack.DefinePlugin({
        REACT_APP_SERVER_URL: JSON.stringify(process.env.BASE_URL),
      }),
      new BrotliPlugin({
        asset: '[path].br[query]',
        test: /.(js|css|html|svg)$/,
        threshold: 10240,
        minRatio: 0.8,
      }),
      new NodePolyfillPlugin(),
    ],
  })
}

my webpack.dev.js:

const path = require('path')
const merge = require('webpack-merge')
const webpack = require('webpack')
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')
const common = require('./webpack.common')

module.exports = () => {
  // location and env are `development` by default
  // https://webpack.js.org/plugins/define-plugin/
  return merge(common, {
    mode: 'development',
    devtool: 'inline-source-map',
    devServer: {
      static: path.join(__dirname, 'dist'),
      compress: true,
      host: 'localhost',
      port: 3000,
      historyApiFallback: true,
      // https://webpack.js.org/configuration/dev-server/#devserverproxy
      proxy: [
        {
          context: ['/auth', '/api'],
          target: 'http://localhost:3001',
          secure: false,
        },
      ],
    },
    plugins: [
      new webpack.DefinePlugin({
        REACT_APP_SERVER_URL: JSON.stringify('http://localhost:3001'),
      }),
      new NodePolyfillPlugin(),
    ],
  })
}

how to know when websocket upgrade fails in socket.io

i am using socket.io in a simple javascript app. I want to alert the user when upgrade to websocket fails due to any reason and HTTP long-polling is used as a fallback, so user knows that connection is not optimal.

I have read the socket.io documentation, websocket upgrade troubleshoot page and faq page. I know when upgrade to websocket is successful (e.g. socket.io.engine.on("upgrade", () => {});, but I don’t find the opposite there.

Apply correct CSS Animation to HTML ID element

I am trying to add an animation in ID “Rangasala” of the following HTML Code:

  <section id="showcase">
        <div class="container">
            <div class="bg">
                <h1 id="Rangasala"></h1>
                <p>Welcome to the Website of the Itahari Rangasala Karate Dojo</p>
            </div>
        </div>
    </section>

My CSS for fading animation:

@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(-20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.fadeIn {
    animation: fadeIn 2s ease-in-out forwards;
}

My JS Code:

document.addEventListener("DOMContentLoaded", () => {
    // Background image slider
    const showcase = document.getElementById("showcase");
    const images = [
        "./img/Dojo2.jpg",
        "./img/Dojo1.jpg",
        "./img/Dojo3.jpg"
    ];
    let index = 0;

    function changeBackground() {
        showcase.style.backgroundImage = `url('${images[index]}')`;

        // Apply clip-path and center only for Dojo3.jpg
        if (images[index].includes("Dojo3.jpg")) {
            showcase.style.clipPath = "inset(10% 0 0 0)";
            showcase.style.backgroundPosition = "center";
        } else {
            showcase.style.clipPath = "none";
            showcase.style.backgroundPosition = "center";
        }

        index = (index + 1) % images.length; // Loop through images
    }

    // Set initial background and start changing every 3 seconds
    changeBackground();
    setInterval(changeBackground, 3000);

    // Typed.js initialization
    var typed = new Typed('#Rangasala', {
        strings: ['Itahari Rangasala Karate Dojo'],
        typeSpeed: 50,
        backSpeed: 25,
        loop: true,
        startDelay: 1000,
        backDelay: 1500,
        onComplete: () => {
            // Add animation class after Typed.js completes
            const rangasalaElement = document.getElementById("Rangasala");
            rangasalaElement.classList.add("fadeIn");
        }
    });

    // Blur effect
    const bg = document.querySelector('.bg');
    let load = 0;
    let int = setInterval(blurring, 30);

    function blurring() {
        load++;
        if (load > 99) {
            clearInterval(int);
        }
        bg.style.filter = `blur(${scale(load, 0, 100, 30, 0)}px)`;
    }

    // Utility function for scaling
    function scale(num, in_min, in_max, out_min, out_max) {
        return ((num - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min;
    }
});

I want the “Rangasala” ID to show “Itahari Rangasala Karate Dojo” on fading appear animation but it is working out.
Here is the Screenshot of my FrontEnd running:
Front End

How to make this image hover effect in website?

image warp effect

How can I create the effect shown in this image, where the part of the image under the mouse pointer appears to bend or warp as the cursor moves over it? I am new to web development and don’t have any experience with implementing such interactive effects. Could you please explain if this effect is possible to achieve using HTML, CSS, and JavaScript, or if it requires additional libraries like Three.js or GSAP? Also, if possible, I would appreciate a step-by-step guide or example code to help me understand how to implement it.

How does React’s useCallback read the variable in closures

In the following example, when the button is clicked, cb2 uses the memoized function. However, why doesn’t cb2 use the first render closures (countVal: 0)?

function TestHook() {

  const [count, setCount] = useState(0)
  let countVal = 0

  const cb = useCallback(() => {
    console.log('cb dep [count]', count, countVal)
  }, [count])

  const cb2 = useCallback(() => {
    console.log('cb2 dep []', count, countVal)
  }, [])

  useEffect(() => {
    cb() // first time: 0, 0 second time: 1, 0 
    cb2() // first time: 0, 0 second time: 0, 1
  })

  const add = () => {
    console.log('add', count)
    countVal ++
    setCount(count + 1)
  }

  return (
    <>
      <button onClick={add}>add</button>
    </>
  );
}

Question:
Can anyone explain the result of cb2() after a re-render?

How to create Jquery or Vanilla JS advanced range slider based pricing calculator?

I’ve been trying to create an advanced pricing calculator showcase for my client’s website.

Here is what i actually need;

I’will have 3 different price and value changer;

  1. Employee
  2. Office Number
  3. Benefits

As you can see on the image, those 3 price/value changers will do change 4 different values on the right depends on the left side value chances.

When the values higher up or selected any benefits; The “with Ozo” background will be filled like %3 but the “without Ozo” background will be filled like 13% (I’m using :before element for the background filling). Also the prices of both blocks will be increase but the “without Ozo” will be increased %15 more than the “with Ozo”. On the other hand when the people number every 15 will add 1 point “HR/Finance employees involved” and 1.5 hour to “hours spent per month” sections.

For the “What benefits do you offer?” tags each will increase only the “without Ozo” part by adding %10 more to the current price.

I know i designed something crazy to complete for my design but now i’m unable to get calculated.

Advanced Price Calculator

Here is what i did so far;

const costRanges = document.querySelectorAll('.cost_item input');

function handleUpdate() {
    const suffix = this.dataset.sizing || '' ;
    var rangeType = this.value+suffix;
    document.documentElement.style.setProperty(`--${this.name}` , rangeType );
}

costRanges.forEach(input => {
    input.addEventListener('change' , handleUpdate);
});
costRanges.forEach(input => {
    input.addEventListener('mousemove' , handleUpdate);
});


(function() {
    const rangeEmployee = document.querySelector('input[type="range"]#employee');
    const rangeCountry = document.querySelector('input[type="range"]#country');

    const rangeEmployeeValue = function(){
        const newValue = rangeEmployee.value;
        const target = document.querySelector('.wOzoValue');
        target.innerHTML = newValue;
    }

    const rangeCountryValue = function(){
        const newValue = rangeCountry.value;
        const target = document.querySelector('.woOzoValue');
        target.innerHTML = newValue;
    }

    rangeEmployee.addEventListener("input", rangeEmployeeValue);
    rangeCountry.addEventListener("input", rangeCountryValue);

})();

Jsonata how to avoid auto change in order javascript

I have array of objects as sample below.
After JSONata evaluation, the order of array of object changes. string with numeric id appears before i.e id 5 appears before id 4a.

How to avoid this change in order

var data = [
    {
        "id": 1,
        "body": "First Item",
        "severity": 1,
        "status": 0
    },
    {
        "id": 2,
        "body": "Second Item",
        "severity": 2,
        "status": 1
    },
{
        "id": 3,
        "body": "third Item",
        "severity": 4,
        "status": 2
    }, 
{
        "id": 4a,
        "body": "four Item",
        "severity": 2,
        "status": 1
    },
{
        "id": 5,
        "body": "five Item",
        "severity": 2,
        "status": 3
    }
]

var result = JSONata(query).evaluate(data)

How to use ast to parse javascript code and find out the execution conditions of specified methods

Issue with Parent Condition Context in Else Block During AST Traversal

I’m working on a JavaScript code analysis tool that traverses the Abstract Syntax Tree (AST) to analyze function calls and their conditions. The goal is to dynamically generate a condition chain for each function call based on nested if, else if, and else statements.

Problem Description

When processing an else block, I’m unable to correctly access the parent condition (parent.condition) to generate the negation of the preceding if condition. This results in incorrect condition chains for function calls inside the else block.

Here’s a simplified version of the code I’m analyzing:

javascript

复制

function foo(a, b) {
    var c = 100;
    if (c > a) {
        if (a > 200) {
            alert(1);
        } else if (a > 100) {
            alert(2);
        } else {
            alert(3); // Condition here is incorrect
        }
    }
}

Expected Output

For the else block (alert(3)), the condition should be:

复制

100 > a 并且 非(a > 200) 且 非(a > 100)

However, the current implementation generates incorrect conditions because the parent condition context is not properly maintained.

Current Implementation

Here’s the relevant part of my code:

javascript

复制

if (
    node.type === 'BlockStatement' &&
    parent.type === 'IfStatement' &&
    parent.alternate === node
) {
    // Attempt to get the parent condition
    const parentCondition = currentConditionContext.parent.condition; // ❌ Fails here
    currentConditionContext = {
        type: 'else',
        condition: `非(${parentCondition})`,
        parent: currentConditionContext.parent.parent, // Incorrect parent reference
        siblingNegation: null
    };
}

Issue

The problem occurs because:

  1. The else block incorrectly skips a level when referencing the parent context (parent.parent).

  2. The parent condition is not accessible due to the incorrect parent reference.

Question

How can I properly maintain the parent condition context for else blocks to generate the correct negation of the preceding if condition?

Desired Solution

I need a way to:

  1. Correctly reference the parent condition context for else blocks.

  2. Generate the negation of the preceding if condition dynamically.

  3. Ensure the condition chain is accurate for nested if-else structures.

Additional Context

  • I’m using esprima for parsing, estraverse for traversal, and escodegen for code generation.

  • The condition chain should support arbitrary levels of nesting.

Here’s the full code for reference:

javascript

复制

// Full code implementation

Any guidance or suggestions would be greatly appreciated!


This question is clear, concise, and provides all the necessary context for someone to understand and help with your issue. You can replace the // Full code implementation comment with your actual code if needed.

this is my code, The following code does not achieve the desired effect

import esprima from 'esprima';
import estraverse from 'estraverse';
import escodegen from 'escodegen';

export function analyzeFunctionCalls(code, functionName, methods) {
    try {
        const ast = esprima.parseScript(code, { range: true, tokens: true, comment: true });
        const functionCalls = [];
        const variableMap = {};
        
        // 树形条件链管理(使用根节点初始化)
        let currentConditionNode = { 
            condition: null, 
            parent: null, 
            children: [] 
        };

        estraverse.traverse(ast, {
            enter: (node, parent) => {
                // 变量声明处理
                if (node.type === 'VariableDeclaration') {
                    node.declarations.forEach(declaration => {
                        if (declaration.init) {
                            variableMap[declaration.id.name] = escodegen.generate(declaration.init);
                        }
                    });
                }

                // 处理 if 语句
                if (node.type === 'IfStatement') {
                    const condition = processCondition(node.test, variableMap);
                    
                    // 创建新的条件节点并链接到当前节点
                    const newNode = {
                        condition: condition,
                        parent: currentConditionNode,
                        children: []
                    };
                    
                    currentConditionNode.children.push(newNode);
                    currentConditionNode = newNode;
                }

                // 处理 else if
                if (
                    node.type === 'IfStatement' &&
                    parent.type === 'IfStatement' &&
                    parent.alternate === node
                ) {
                    // 获取父 if 的条件
                    const parentIfCondition = currentConditionNode.parent.condition;
                    const currentCondition = processCondition(node.test, variableMap);
                    
                    // 创建 else if 节点
                    const newNode = {
                        condition: `非(${parentIfCondition}) 且 ${currentCondition}`,
                        parent: currentConditionNode.parent, // 关键修正:父节点指向原 if 的父级
                        children: []
                    };
                    
                    currentConditionNode.parent.children.push(newNode);
                    currentConditionNode = newNode;
                }

                // 处理 else 块
                if (
                    node.type === 'BlockStatement' &&
                    parent.type === 'IfStatement' &&
                    parent.alternate === node
                ) {
                    // 获取父 if 的条件
                    const parentIfCondition = currentConditionNode.parent.condition;
                    
                    // 创建 else 节点
                    const newNode = {
                        condition: `非(${parentIfCondition})`,
                        parent: currentConditionNode.parent, // 关键修正:父节点指向原 if 的父级
                        children: []
                    };
                    
                    currentConditionNode.parent.children.push(newNode);
                    currentConditionNode = newNode;
                }

                // 收集函数调用
                if (node.type === 'CallExpression') {
                    const callee = node.callee;
                    const fullCondition = getFullConditionChain(currentConditionNode);
                    
                    if (
                        (callee.type === 'Identifier' && methods.includes(callee.name)) ||
                        (callee.type === 'MemberExpression' &&
                         callee.object.name === functionName &&
                         methods.includes(callee.property.name))
                    ) {
                        functionCalls.push({
                            call: escodegen.generate(node),
                            condition: fullCondition
                        });
                    }
                }
            },
            leave: (node) => {
                // 离开 if 语句时回溯到父节点
                if (node.type === 'IfStatement') {
                    currentConditionNode = currentConditionNode.parent;
                }
            }
        });

        return functionCalls;
    } catch (error) {
        console.error('Error parsing code:', error);
        return [];
    }
}

// 生成完整条件链(从根到当前节点)
function getFullConditionChain(node) {
    const path = [];
    let current = node;
    while (current && current.condition !== null) {
        path.unshift(current.condition);
        current = current.parent;
    }
    return path.join(' 并且 ');
}

// 优化后的条件处理
function processCondition(testNode, variableMap) {
    return escodegen.generate(testNode)
        .replace(/bw+b/g, m => variableMap[m] || m)
        .replace(/>=/g, '≥')
        .replace(/<=/g, '≤')
        .replace(/===/g, '等于')
        .replace(/==/g, '等于')
        .replace(/!=/g, '≠')
        .replace(/>/g, '>')
        .replace(/</g, '<')
        .replace(/||/g, ' 或 ')
        .replace(/&&/g, ' 且 ')
        .replace(/!/g, '非');
}
console.log(analyzeFunctionCalls(`


function foo(a, b) {
    var c = 100
    if(c > a){
        if( a > 200){
            alert(1)
            alert(4)
        }else if(a > 100){
            alert(2)
            if(b > 200){
                alert(5)
            }else{
                alert(6)
            }
            alert(7)
        }else{
            alert(3)

            if(b > 200){
                alert(8)
            }else{
                alert(9)
            }
            alert(10)
        }    
    }
}




`, "DV",["alert"]));

expected result

[
{ call: 'alert(1)', condition: '100>a 并且 a>200' },
{ call: 'alert(4)', condition: '100>a 并且 a>200' },
{ call: 'alert(2)', condition: '100>a 并且 非(a>200) 且 a>100' },
{ call: 'alert(5)', condition: '100>a 并且 非(a>200) 且 a>100 并且 b>200' },
{ call: 'alert(6)', condition: '100>a 并且 非(a>200) 且 a>100 并且 非(b>200)' },
{ call: 'alert(7)', condition: '100>a 并且 非(a>200) 且 a>100' },
{ call: 'alert(3)', condition: '100>a 并且 非(a>200) 且 非(a>100)' }, // ✅ 正确
{ call: 'alert(8)', condition: '100>a 并且 非(a>200) 且 非(a>100) 并且 b>200' }, // ✅
{ call: 'alert(9)', condition: '100>a 并且 非(a>200) 且 非(a>100) 并且 非(b>200)' }, // ✅
{ call: 'alert(10)', condition: '100>a 并且 非(a>200) 且 非(a>100)' } // ✅
]

actual result

[
  { call: 'alert(1)', condition: '100 > a 并且 a > 200' },
  { call: 'alert(4)', condition: '100 > a 并且 a > 200' },
  {
    call: 'alert(2)',
    condition: '100 > a 并且 a > 200 并且 非(a > 200) 且 a > 100'
  },
  {
    call: 'alert(5)',
    condition: '100 > a 并且 a > 200 并且 非(a > 200) 且 a > 100 并且 b > 200'
  },
  {
    call: 'alert(6)',
    condition: '100 > a 并且 a > 200 并且 非(a > 200) 且 a > 100 并且 非(非(a > 200) 且 a > 100)'
  },
  {
    call: 'alert(7)',
    condition: '100 > a 并且 a > 200 并且 非(a > 200) 且 a > 100'
  },
  { call: 'alert(3)', condition: '100 > a 并且 a > 200 并且 非(a > 200)' },
  {
    call: 'alert(8)',
    condition: '100 > a 并且 a > 200 并且 非(a > 200) 并且 b > 200'
  },
  {
    call: 'alert(9)',
    condition: '100 > a 并且 a > 200 并且 非(a > 200) 并且 非(非(a > 200))'
  },
  { call: 'alert(10)', condition: '100 > a 并且 a > 200 并且 非(a > 200)' }
]

Is there a god to help me

thank you

my 3 hourly forecast data is not reflecting on my hd have shown all the able forecast

I am on my first JavaScript project and I am building a weather app.

I was able to extract the 3 hourly forecast Data but it is only showing the first data. Like only 21:00 data in my html but the rest is not reflecting. It should have shown all the able forecast data.

While writing my html I wrote 6 elements that are responsible for holding the forecast data but I actually needed 8. So I created the forecast item as a way of creating the remaining html. I am meant to add it by the forecast container.innerHTML += forecast item. I didn’t do that yet because only 1 of the 6 I already had showed the forecast data. What I want is for the 3 hourly forecast data to automatically reflect in the html for every 24 hours

async function getForecast() {
  try {

    // const citySearch = document.getElementById('search-city').value;
    const apiKey = 'APIKEY';
    const forecastFullUrl = `https://api.openweathermap.org/data/2.5/forecast?q=Dudley&appid=${apiKey}&units=metric`;

    console.log('fetching forecast URL:', forecastFullUrl)
    const forecastResponse = await fetch(forecastFullUrl)
    const forecastData = await forecastResponse.json()
    console.log(forecastData);

    displayCurrentForecastData(forecastData.list);
  } catch (error) {
    console.error('error fetching hourly forecast data:', error);
    alert('Failed to fetch hourly forecast data');
  }
}
getForecast();

function displayCurrentForecastData(forecastList) {


  // compare today date with the date in the dorecast data and return only the ones that matches today's date

  const currentDate = new Date();
  const currentDateStringToShowOnMainPage = currentDate.toISOString().split('T')[0];
  // to make the date on the main page be the current date
  document.getElementById('current-date').textContent = currentDateStringToShowOnMainPage;

  //  to only shown current day's weather forecast
  const currentDayForecast = forecastList.filter((forecast) => {

    const time = new Date(forecast.dt * 1000)
    const forecastDateString = time.toISOString().split('T')[0];
    return forecastDateString === currentDateStringToShowOnMainPage;
  })


  // this to make  more html children since i only created 6 spaces in th e html for the 3 hours weather details
  const forecastContainer = document.getElementById('selected-hour-details')
  // forecastContainer.innerHTML = '';

  currentDayForecast.forEach((forecast, index) => {

    const forecastItem = document.createElement('div');
    forecastItem.className = 'selected-hour-details';
    const time = new Date(forecast.dt * 1000)
    const timeString = time.toLocaleTimeString([], {
      hour: "2-digit",
      minute: "2-digit"
    });

    const temp = forecast.main.temp;
    const description = forecast.weather[0].description;
    const icon = `http://openweathermap.org/img/wn/${forecast.weather[0].icon}`;

    // to update the 3 hourly html with the forecast details

    document.querySelector('.forecasttime').textContent = timeString;
    document.querySelector('.forecasttemp').textContent = `${temp}°C: ${description}`;
    document.querySelector('.weather-icon').src = icon;

    // /create more spaces

    forecastItem.innerHTML = `
              <span class="forecasttime">${timeString}</span>
              <img class="weather-icon" src="${icon}" alt="weather icon"/>
              <span class="forecasttemp">${temp}°C: ${description}</span>
            `
    forecastContainer.innerHTML += forecastItem;
  })
}
<div class="selected-hour-weather-details" id="selected-hour-weather-details">

  <div class="specific-hours">
    <span class="forecasttime">00:00</span>
    <img class="weather-icon" src="" alt="weather icon"/>
    <span class="forecasttemp">4°</span>
  </div>

  <div class="specific-hours">
    <span class="forecasttime">01:00</span>
    <img class="weather-icon" src="" alt="weather icon"/>
    <span class="forecasttemp">5•</span>
  </div>

  <div class="specific-hours">
    <span class="forecasttime">02:00</span>
    <img class="weather-icon" src="" alt="weather icon"/>
    <span class="forecasttemp">5•</span>
  </div>

  <div class="specific-hours">
    <span class="forecasttime">03:00</span>
    <img class="weather-icon" src="" alt="weather icon"/>
    <span class="forecasttemp">5•</span>
  </div>

  <div class="specific-hours">
    <span class="forecasttime">04:00</span>
    <img class="weather-icon" src="" alt="weather icon"/>
    <span class="forecasttemp">5•</span>
  </div>

  <div class="specific-hours">
    <span class="forecasttime">05:00</span>
    <img class="weather-icon" src="" alt="weather icon"/>
    <span class="forecasttemp">5•</span>
  </div>
</div>

weird behaviour in useeffect setInterval [duplicate]

In the strict mode of react it is running this function “fetchLiveChatMsg(liveChatId);” twice in setInterval, but when the unmounting happen it still keeps running this function even the interval is clear but in the non-strict mode of react everything is working fine

NOTE: I’ve already tried the useRef in intervalId, pageToken, it is still working the same

import { useEffect, useRef } from "react";
import LiveChatMsg from "./LiveChatMsg";
import { useDispatch, useSelector } from "react-redux";
import { addLiveMsg } from "../utils/LiveChatSlice";

const LiveChat = ({videoId}) => {
    const dispatch = useDispatch();
    let intervalId;
    let pageToken;

    const liveMessages = useSelector((store) => store.liveChat.messages);

    const fetchLiveChatMsg = async (liveChatId) => {
        const response = await fetch(`https://www.googleapis.com/youtube/v3/liveChat/messages?pageToken=${pageToken ? pageToken : ""}&liveChatId=${liveChatId}&part=snippet,authorDetails&key=${import.meta.env.VITE_GOOGLE_API_KEY}&maxResults=1`);

        const data = (await response.json());

        pageToken = data.nextPageToken;
        console.log(pageToken);
        console.log(data);
        dispatch(addLiveMsg(data?.items[0]));
    }

    const fetchLiveId = async () => {
        const response = await fetch(`https://www.googleapis.com/youtube/v3/videos?part=liveStreamingDetails&id=${videoId}&key=${import.meta.env.VITE_GOOGLE_API_KEY}`);
        
        const liveChatId = (await response.json())?.items[0]?.liveStreamingDetails?.activeLiveChatId;
        
        if(liveChatId) {
            console.log(liveChatId);
            intervalId = setInterval(() => {
                fetchLiveChatMsg(liveChatId);
            }, 3000);
        }
    }

    useEffect(() => {
        fetchLiveId();

        return () => {
            console.log(intervalId);
            clearInterval(intervalId);
        }
    }, []);

    return (
        liveMessages && <div className="w-2/5 flex border-[1.5px] rounded-xl p-[8px] h-[450px] flex-col-reverse gap-[10px] overflow-y-scroll bg-gray-50">
            {
                liveMessages.map((el, idx) => <LiveChatMsg key={idx} profile={el?.authorDetails?.profileImageUrl} author={el?.authorDetails?.displayName} msg={el?.snippet?.displayMessage} />)
            }
        </div>
    );
};

export default LiveChat;

I want while unmounting the “fetchLiveChatMsg(liveChatId);” function doesn’t run because the timer id of the setinterval is cleared