How do I avoid adding the same product to the cart database?

I am working on my store project using JS. When I click on the add-to-cart button, an array with objects – image, name, price, is added to my storage. But, I can add such arrays, products, infinitely to the cart storage. How can I prevent adding the same product to the cart?

addToCard = (e) => {
    if (e.target.closest(".add-to-cart")) {
      
      let price = e.target.parentElement.parentElement.dataset.price;
      let name = e.target.parentElement.parentElement.parentElement.dataset.name;
      let img = e.target.parentElement.parentElement.parentElement.dataset.img;
      
      const cartItems = { price, name, img };

      apiService.post("/order", cartItems).then(() => {
       this.setState({
          ...this.state,
          orderCart: this.state.orderCart?.concat(cartItems),
        })
      })
      
      useToastNotification({
        message: "Product in the cart!",
        type: TOAST_TYPE.success,
      });
    }
  };

I want to add an item to the cart, only once. My items have different names. How can I check the variable name in the array and not add the product with that name to the storage?

How to run Node.js code in the browser when it doesn’t access files or system APIs?

I have some JavaScript code that runs perfectly in Node.js, for example:

const someModule = require("some-module");

const result = someModule.doSomething();
console.log(result);

This code does not access files, the network, or other Node-specific resources, and the module itself is purely a logic module that works offline. So in theory, it should work in a browser since Node.js and browser JavaScript use the same language.

I am not looking for a Node server solution. I want a solution that works with pure HTML, JS, and CSS, so the page can remain completely static, like a page hosted on GitHub Pages.

The problem is that when I try to run the same logic in the browser (for example, by importing the module via a CDN), I often encounter errors related to Node-specific APIs that don’t exist in browsers.

I am looking for a general approach to make this kind of Node.js code run in a browser.


Example of my current issue:

Importantly, I am not asking for a fix only for BIP39. I am trying to understand the general approach to this kind of issue, so that whenever the same problem happens with other Node.js modules that are purely logic-based and offline, I can apply the same solution.

Node.js code (index.js):

// index.js
// npm install bip39

const bip39 = require("bip39");

const mnemonic = bip39.generateMnemonic();
console.log(mnemonic);

Attempt in the browser (index.html):

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>BIP39 Demo</title>
  <style>
    body {
      font-family: sans-serif;
      text-align: center;
      margin-top: 50px;
    }
    button {
      padding: 10px 20px;
      font-size: 16px;
      cursor: pointer;
    }
    #output {
      margin-top: 20px;
      font-weight: bold;
    }
  </style>
</head>
<body>
  <h1>BIP39 Random Seed Words</h1>
  <button id="generate">Generate Mnemonic</button>
  <div id="output"></div>

  <script type="module">
    import bip39 from "https://cdn.skypack.dev/bip39";

    const button = document.getElementById("generate");
    const output = document.getElementById("output");

    button.addEventListener("click", () => {
      const mnemonic = bip39.generateMnemonic();
      output.textContent = mnemonic;
    });
  </script>
</body>
</html>

NestJS Cron Scheduler Stops Running Unexpectedly

I have a NestJS application running on a Windows Server, where the app is installed as a Windows Service (via nssm).The issue: the 1-minute and 5-minute schedulers stop running unexpectedly.

Inside the app I use @nestjs/schedule with 5 cron jobs:

  • one runs every 1 minute

  • one runs every 5 minutes

  • others run every 10 min, 15 min, 1 hour, etc.

The issue: the 1-minute and 5-minute jobs stop firing after some time, and not restarted, but the rest continue normally. The service itself remains running, and there are no error logs.

Example code for the 5-minute job:

import { Cron } from '@nestjs/schedule';
import { Injectable, Logger } from '@nestjs/common';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Cron('*/5 * * * *')
  async scheduledHandleCronOld() {
    this.logger.log('Old File Processing Job >> Starting scheduled handleCronOld...');
    try {
      if (this.config.get('SFTP_FILE_FORMAT') === 'OLD') {
        await this.handleCronOld(null);
      } else {
        this.logger.log('Old File Processing Job >> Ended due to config is NEW File Format...');
      }
    } catch (error) {
      this.logger.error(`Old File Processing Job >> Scheduler error: ${error.message}`);
    }
  }
}

How to not trigger Firefox’s strict Content Security Policy by my extension

I am currently contributing on an extension, and the main problem is that on Firefox, the CSP is being triggered, which causes quite a few issues. Mainly it seems to block the injection of dynamic CSS, which I thought I removed, although it still gets triggered. Just for reference, the website I am targeting is modrinth. This is the repo if you want a full look at the code (it’s probably really bad code) blueRinth, however, the main problem I suspect is in my injected.js, where the code is:

document.onreadystatechange = function () {
  const projectRegex =
    /^https?://modrinth.com/(?:project|mod|resourcepack|shader|datapack|modpack)/([^/]+)/;
  const projectIdTest = projectRegex.exec(window.location.href);
  const projectId =
    projectIdTest != null && projectIdTest.length > 1 ? projectIdTest[1] : null;
  if (projectId !== null) {
    runBanner(projectId);
    return;
  }
  pageSupportsBanners = false;
};

useNuxtApp()._middleware.global.push(function handleRoute(to, from) {
  if (to.name.startsWith("type-id")) {
    const { id } = to.params;
    console.log("entering project", id);
    runBanner(id);
  } else if (from.name.startsWith("type-id")) {
    const { id } = from.params;
    //console.log("leaving project", id);
    const containers = document.getElementsByClassName("banner-container");
    for (let container of containers) {
      document.body.removeChild(container);
    }
    pageSupportsBanners = false;
  }
});

let pageSupportsBanners = false;
const fallbackimage =
  "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAnSURBVHhe7cEBDQAAAMKg909tDjcgAAAAAAAAAAAAAAAAAAAA4FwNQEAAAQtzTh0AAAAASUVORK5CYII=";
let banner = fallbackimage;

async function runBanner(id) {
  console.log("runBanner called with id:", id);
  pageSupportsBanners = true;
  const apibase = "https://api.modrinth.com/v3/project/";

  try {
    const response = await fetch(apibase + id);
    if (!response.ok) {
      console.error("blueRinth: Response failed during banner loading.");
      return;
    }
    const data = await response.json();
    console.log("Project API data:", data);
    console.log("gallery:", data.gallery);
    data.gallery.forEach((entry) => {
      if (entry.featured === true) {
        banner = entry.url;
        applyBanners();
      }
    });
  } catch {
    console.error(
      "blueRinth: Something failed during banner loading. Please contact WorldWidePixel."
    );
  }
}

function applyBanners() {
  console.log("applyBanners called, banner:", banner);
  if (pageSupportsBanners) {
    const bannerContainer = document.createElement("div");
    const bannerStyles = document.createElement("style");
    bannerStyles.innerHTML = `
  .banner-image {
    background-image:
    linear-gradient(0deg, var(--color-bg) 0%, rgba(0, 0, 0, 0) 200%),
    url(${banner}) !important;
  }
  `;
    document.head.appendChild(bannerStyles);
    bannerContainer.classList.add("banner-container");
    const bannerImage = document.createElement("div");
    bannerImage.classList.add("banner-image");
    bannerContainer.appendChild(bannerImage);
    const bannerBg = document.createElement("div");
    bannerBg.classList.add("banner-bg");
    document.body.appendChild(bannerBg);
    document.body.appendChild(bannerContainer);
    bannerContainer.style.opacity = "100%";
  }
}

Here is the text of the CSP errors i face, I have little idea what they really mean, hence why I’m here:

Content-Security-Policy: (Report-Only policy) The page’s settings would block an inline script (script-src-elem) from being executed because it violates the following directive: “script-src ‘self’”. Consider using a hash (‘sha256-JBmyBqGA3TPyBg9fUy2esK5fafHmvdYH2GunnhLcvUw=’) or a nonce.

Content-Security-Policy: The page’s settings blocked an inline style (style-src-elem) from being applied because it violates the following directive: “style-src https://m.stripe.network”. Consider using a hash (‘sha256-dd4J3UnQShsOmqcYi4vN5BT3mGZB/0fOwBA72rsguKc=’, requires ‘unsafe-hashes’ for style attributes) or a nonce.

I have tried moving all my css to separate files and declaring it in my manifest.json, then in my content.js, switching themes baed on those files, however this does not work. The problem may also arise in my content.js, where the main theme switching is handled.

How can I implement syntax highlighting across the entire project files in VS Code?

In my case, while developing a Blazor web app, I found that some files have syntax highlighting and others do not. It primarily consists of HTML, C#, and JavaScript, which can occasionally be combined into a single file.

Here’s the screenshot of it:

VS Code files comparison

It appears off, especially if the JavaScript code expands in size.


And here’s the VS Code relevant information (VS Code > Help > About):

Vs Code About

Also, note that I am on Windows. Yet, I have no idea why it occurred.

Why am I getting “This attempt to set a cookie via a Set-Cookie header was blocked due to user preference” in my Next.js + Express app?

I’m building a blogging app with Next.js (frontend) and Express.js (backend).
The backend is deployed on Render, and the frontend runs locally on http://localhost:3000.

I’m trying to set cookies from my Express backend using Set-Cookie, but in the browser console I always get this error:

This attempt to set a cookie via a Set-Cookie header was blocked due to user preference

Here’s what I already tried:

  • Added CORS config on backend with credentials: true

  • On frontend, I’m using fetch with credentials: “include”

  • Tried setting cookie options like:

res.cookie("token", token, {
  httpOnly: true,
  secure: true,
  sameSite: "none",
});
  • Verified that my backend is actually sending the Set-Cookie header in the response

Checked on Chrome/Edge — still blocked

My backend response headers look correct, but the cookie is never stored.

From what I understand, this error can be related to:

  • Cross-site cookies being blocked by default

  • Third-party cookies disabled in the browser

  • SameSite/Secure misconfiguration when frontend and backend are on different domains

What I need help with:

Is this purely a browser setting issue (e.g., Chrome blocking cross-site cookies), or something I should fix in my backend config?

If it’s backend related, what is the correct way to set cookies so they are not blocked?

Do I need to change cookie options (SameSite, Secure, domain) when frontend = localhost and backend = Render domain?

How do I make sure this will also work in production (with custom domain on both frontend and backend)?

Excel Office.js displayDialogAsync fails with “Internal Error” on Desktop version 2507

I am developing an Excel add-in that needs to authenticate the user using OAuth. To do this I am calling Office.context.ui.displayDialogAsync to open the authorization page in a dialog.

The code works fine when I run the add-in in Excel Online and also previous versions on or before 2506, but when I test the exact same add-in in Excel Desktop (latest build 2507) it fails immediately with an internal error.

Here is the code I am using to open the dialog:

function openAuthDialog(authUrl) {
    app.log("auth url : " + authUrl);
    var codeChallenge = sessionStorage.getItem("code_challenge");

    Office.context.ui.displayDialogAsync(
        authUrl + "?scope=openid&client_id=" + clientId +
        "&response_type=code&redirect_uri=" + panelURL +
        "&code_challenge=" + codeChallenge +
        "&code_challenge_method=S256",
        { height: app.optimizeHeight(), width: app.optimizeWidth() },
        function (asyncResult) {
            if (asyncResult.status === Office.AsyncResultStatus.Failed) {
                console.error("Error from dialog => " + asyncResult.error.code + ": " + asyncResult.error.message);
                window.location.assign(app.host_url + "excel/AppCommon/connect.html");
            } else {
                dialog = asyncResult.value;
                dialog.addEventHandler(Office.EventType.DialogMessageReceived, processMessage);
                dialog.addEventHandler(Office.EventType.DialogEventReceived, dialogCallback);
            }
        }
    );
}

When I run this on Excel Desktop (version 2507), I get this error:

OSF.DDA.AsyncResulterror: OSF.DDA.Errorcode: -2147024809
message: “An internal error has occurred.”
status: “failed”

How to embed a link to the home page in a custom WordPress block

I’m developing a custom WordPress block using the block.json + edit.js + save.js pattern (Block API v2).
I’m not using registerBlockType() directly in JS nor the old PHP-only approach, but relying on block.json to register editorScript, viewScript etc.

I need to pass a dynamic homepage url into both my edit and save components, but wp_localize_script doesn’t seem to work with the file-based editorScript entry in block.json.

How can I correctly inject a homepage url into my edit.js/save.js when using the block.json workflow?

is there a difference between elements created dynamically with JavaScript and elements in HTML

take the code below:

    contentsDiv.innerHTML = container.outerHTML;

    if(contentsDiv.firstChild === container) console.log('true');

in this code, contentsDiv is a div created in my html file while container is a div with class=’container’ created with JavaScript. Then i insert container into contentsDiv. But when i check to see if the contentsDiv’s firstChild is equal to container (which it is in the DOM) it doesnt console.log(‘true’)

I tried

    console.log(typeof(contentsDiv.firstChild))
    console.log(typeof(container))

both returned to be an object but somehow they don’t resolve to be equal when i use ‘==’ or ‘===’

DragEnter event not firing reliably when mouse enters the drop zone

If you look at the SSCCE below you’ll see that when files are dragged from outside my drop-zone, the CSS attribute –fade-time is modified and the target begins to pulsate so the user knows it’s time to drop their bundle. The problem is that it doesn’t seem to be 100% reliable with the dragEnter event not always firing.

I can try deferring the event till the “container” element and then checking target.id=”div1″. Or maybe a “Once only” event dragOver to do what dragEnter used to do?

Any ideas on how to make the behaviour deterministic would be great.

document.addEventListener("DOMContentLoaded", (e) => {
  document.addEventListener('drop', function(e) {
    e.preventDefault()
  })
  document.addEventListener('dragenter', function(e) {
    e.preventDefault();
    e.dataTransfer.dropEffect = "none"
  })
  document.addEventListener('dragover', function(e) {
    e.preventDefault();
    e.dataTransfer.dropEffect = "none"
  })

  const dropZone = document.getElementById("container")
  dropZone.addEventListener("dragenter", (e) => {
    console.log("In enter " + dropZone)
    e.dataTransfer.dropEffect = "copy"
    e.preventDefault()
    e.stopPropagation()
    document.getElementById("div2").style.setProperty("--fade-time", "2.0s")
  })
  dropZone.addEventListener("dragover", (e) => {
    console.log("In over " + dropZone)
    e.dataTransfer.dropEffect = "copy"
    e.preventDefault()
    e.stopPropagation()
  })
  dropZone.addEventListener("dragleave", (e) => {
    console.log("In leave")
    e.dataTransfer.dropEffect = "none"
    e.preventDefault();
    document.getElementById("div2").style.removeProperty("--fade-time")
  })
  dropZone.addEventListener("drop", catchFiles)
})

function catchFiles(e) {
  e.preventDefault();
  document.getElementById("div2").style.removeProperty("--fade-time")
  console.log("File(s) dropped");

  let fileHolder = new FormData()
  let fileCount = 0

  if (e.dataTransfer.items) {
    // Use DataTransferItemList interface to access the file(s)
    [...e.dataTransfer.items].forEach((item, i) => {
      // If dropped items aren't files, reject them
      if (item.kind === "file") {
        const file = item.getAsFile()
        console.log(`… file[${i}].name = ${file.name}`)
        fileHolder.append("file" + i, file, file.name)
        fileCount++
      }
    });
  } else {
    // Use DataTransfer interface to access the file(s)
    [...e.dataTransfer.files].forEach((file, i) => {
      console.log(`… file[${i}].name = ${file.name}`);
      fileHolder.append("file" + i, file, file.name)
      fileCount++
    });
  }
  if (fileCount == 0) {
    alert("Zero files received")
    return
  }
  alert("got " + fileCount + " files")
  return
  const abortControl = new AbortController();
  const signal = abortControl.signal;
  const fetchOpts = {
    signal: signal,
    method: 'POST',
    body: fileHolder,
    cache: "no-cache"
  };
  const response = fetch("https://localhost:7196/upload/PostFormData", fetchOpts).catch(
    err => {
      console.log("Upload failed: " + err.message);
      return
    });
  if (signal.aborted) {
    alert("Cancelled")
    return
  }

}
#container {
  position: relative;
  display: flex;
  width: 120px;
  height: 120px;
  padding: 10px;
  border: 1px solid black;
}

#div1 {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background-color: lightblue;
  cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 300 300'><path fill='%23FFF' stroke='%23E50024' stroke-width='50' d='M150 25 a125 125 0 1 0 2 0z m 2 100 a25 25 0 1 1-2 0z'/></svg>"), auto;
}

#div2 {
  --fade-time: 0;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0%;
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 300 300'><path fill='%23FFF' stroke='%23E50024' stroke-width='50' d='M150 25 a125 125 0 1 0 2 0z m 2 100 a25 25 0 1 1-2 0z'/></svg>");
  animation: pulseImage var(--fade-time) infinite;
}

body>p {
  color: red;
}

div>p {
  font-weight: bold;
}

@keyframes pulseImage {
  from {
    opacity: 0;
  }

  to {
    opacity: 0.7;
  }
}
<h1>File Drop Upload Example</h1>

<p>Drag your file(s) into the Drop Zone</p>

<div id="container">
  <div id="div1">
    <p>File Drop Zone</p>
  </div>
  <div id="div2"></div>
</div>

Video camera freezes when switching from rear to front with Twilio Video in Chrome for Android

Problem Details
I’m developing a video chat app using JavaScript and the Twilio Video SDK. I’ve implemented a feature to allow mobile users to switch between the front and rear cameras.

The problem is as follows:

  • The camera switching functionality works perfectly on iPhone.
  • On Android (using Chrome), the first switch (from the front to the rear camera) works correctly.
  • However, when trying to switch again, from the rear to the front camera, the local video freezes (shows the last frame) or goes black.
  • Interestingly, if I minimize the Chrome browser and reopen it, the front camera activates and the video displays correctly.

This appears to be an issue related to how Chrome on Android releases the rear camera resource before activating the front camera.

My current code performs the following steps to switch cameras:

  1. Get the list of available cameras (video input).
  2. Click the change button to select the device ID of the next camera.
  3. Create a new local video track (LocalVideoTrack) with the new device ID.
  4. UnpublishTrack and stop (track.stop()) the old video track.
  5. Publish the new video track.
  6. Replace the video element in the DOM with the new one.

Below is the relevant code snippet that handles this logic:

Plugin.prototype.checkDevices = function () {
        var that = this;
        var constraints = {
            audio: true,
            video: true
        };
        navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
            that.userStream = stream;
            var nstream = null;
            if (that.options.auto_recording === 4) {
                const tracks = stream.getAudioTracks();
                nstream = new MediaStream();
                nstream.addTrack(tracks[0]);
            } else {
                nstream = stream;
            }
            if (!that.setUpRTCRecorder('own', that.getVideoFrom(false), false, nstream, false)) {
                that.setUpStatRecording();
            }
            navigator.mediaDevices.enumerateDevices().then(function (mediaDevices) {
                var count = 1;
                const select = document.getElementById('video-switch-select');
                that.cameraSelected = 0;
                mediaDevices.forEach(mediaDevice => {
                    if (mediaDevice.kind === 'videoinput') {
                        count++;
                        that.cameras.push({
                            id: mediaDevice.deviceId,
                            label: mediaDevice.label || `Camara ${count}`
                        });
                    }
                });
                if (that.cameras.length > 1) {
                    $(".video-switch-button").on('click', function () {
                        that.cameraSelected++;
                        if (that.cameraSelected >= that.cameras.length) {
                            that.cameraSelected = 0;
                        }
                        console.log("Switching to camera", that.cameraSelected);
                        var toswitch = that.cameras[that.cameraSelected];
                        Twilio.Video.createLocalVideoTrack({
                            deviceId: {exact: toswitch.id}
                        }).then(function (localVideoTrack) {
                            console.log("Adding track", localVideoTrack);
                        const publications = Array.from(that.activeRoom.localParticipant.videoTracks.values());
                            for (var i in publications) {
                                var track = publications[i].track;
                                console.log("Unpublishing track", track);
                                that.activeRoom.localParticipant.unpublishTrack(track);
                                track.stop();
                        }
                            that.activeRoom.localParticipant.publishTrack(localVideoTrack);
                            $('#local-media').html("");
                            document.getElementById('local-media').appendChild(localVideoTrack.attach());
                            if (that.chatOn) {
                                $('#local-media > video').addClass('local-media-oncall-video-chat');
                                $('.user-placeholder').addClass('placeholder-oncall-video-chat');
                            } else {
                                $('#local-media > video').addClass('local-media-oncall-video');
                                $('.user-placeholder').addClass('placeholder-oncall-video');
                            }

                        }).catch(error => {
                            console.error("Error al crear la nueva pista de video:", error);
                            alert("Error al cambiar de cámara: " + error.message);
                    });
                    });
                }
            });
            that.initCB();
        }).catch(function (error) {
            alert('getUserMedia() error: ', error.message);
        });
    };

I’m looking for a solution that allows me to seamlessly switch between the rear and front cameras in Chrome on Android without the video freezing or getting the Could not start video source error.

How to detect mouse over canvas

I’m using a userscript that overrides CanvasRenderingContext2D.prototype.drawImage to replace a specific image (oldimg.png) with a custom image (newimg.png) when it is rendered on a canvas. I would like to detect when the user’s mouse hovers over the area where the new image is drawn and trigger an alert(“hello world”). Since the image is drawn on the canvas (not a regular DOM element), what’s the best way to detect hover interactions with that specific image region? I have tried many tradition routes to select DOM elements but they have not worked due to the new image being drawn on a canvas.

(function() {
    'use strict';

    var coinImageWhite = new Image(500, 500);
    coinImageWhite.src = 'https://agma.io/skins/newimg.png'
    var coinImageBlack = new Image(500, 500);
    coinImageBlack.src = 'https://agma.io/skins/newimg.png'

    var rawSettings = localStorage.getItem('settings');
    var settings = JSON.parse(rawSettings);

    var originalDrawImage = CanvasRenderingContext2D.prototype.drawImage;
    CanvasRenderingContext2D.prototype.drawImage = function (image, sourceX, sourceY, sourceWidth, sourceHeight, targetX, targetY, targetWidth, targetHeight) {
        if ((image.src != undefined)) {

            if (image.src == 'https://agma.io/skins/oldimg.png' || image.src == 'https://agma.io/skins/oldimg.png') {

                if (settings.sDark) {
                    arguments[0] = coinImageBlack;
                    console.log("yo");
                } else {
                arguments[0] = coinImageWhite;
                    console.log("yo");
                }
            }
        }

        return originalDrawImage.apply(this, arguments);
    }

    console.log('Script loaded');
})();

Convert Alpine.js on-click to Datastar data-on*

I have some links on my site which currently uses alpine.js to trigger a function that scrolls to a div on the page and I wish to convert this to use Datastar.js

This is what is currently in the base.html file and the javascript file.

base.html
<div class="flex h-full items-end py-4 gap-x-14 text-white uppercase text-xs font-medium">
    <div><a href="#" x-on:click.prevent="scrollToId('contact')">Contact Us</a></div>
    <div><a href="#" x-on:click.prevent="scrollToId('about')">About us</a></div>
    <div><a href="#" x-on:click.prevent="scrollToId('services')">Services</a></div>
    <div><a href="#" x-on:click.prevent="scrollToId('products')">Products</a></div> </div>

The javascript function is as follows and is imported into index.js then ran through webpack.

export default () => ({
    scrollToId(id) {
        // This is used for the navigation links in the header and footer
        const element = document.getElementById(id);
        if (element) {
            element.scrollIntoView({behavior: 'smooth' });
        }
    },
});

I have tried to convert this to Datastar data-on-click and run the ‘scrollToId’ function but it errors out saying it can’t find the function.

<div><a href="#" data-on-click__prevent="scrollToId('contact')">Contact Us</a></div>
127.0.0.1/:10  GET http://127.0.0.1:8000/assets/components/smoothScroll.js net::ERR_ABORTED 404 (Not Found)
init_embed.js:285 Search endpoint requested!
backend.js:2 Alpine Devtools: waiting for init request...
datastar.js:8 Uncaught datastar runtime error: ExecuteExpression
More info: https://data-star.dev/errors/runtime/execute_expression?metadata=%7B%22plugin%22%3A%7B%22name%22%3A%22on%22%2C%22type%22%3A%22attribute%22%7D%2C%22element%22%3A%7B%22id%22%3A%22%22%2C%22tag%22%3A%22A%22%7D%2C%22expression%22%3A%7B%22rawKey%22%3A%22onClick__prevent%22%2C%22key%22%3A%22click%22%2C%22value%22%3A%22scrollToId%28%27contact%27%29%22%2C%22fnContent%22%3A%22scrollToId%28%27contact%27%29%22%7D%2C%22error%22%3A%22scrollToId+is+not+defined%22%7D
Context: {
  "plugin": {
    "name": "on",
    "type": "attribute"
  },
  "element": {
    "id": "",
    "tag": "A"
  },
  "expression": {
    "rawKey": "onClick__prevent",
    "key": "click",
    "value": "scrollToId('contact')",
    "fnContent": "scrollToId('contact')"
  },
  "error": "scrollToId is not defined"
}
    at pt (webpack://website/./assets/datastar.js?:8:1275)
    at Number.mt (webpack://website/./assets/datastar.js?:10:330)
    at On.e.runtimeErr.error (webpack://website/./assets/datastar.js?:11:876)
    at HTMLAnchorElement.c (webpack://website/./assets/datastar.js?:11:9090)
pt @ datastar.js:8
mt @ datastar.js:10
On.e.runtimeErr.error @ datastar.js:11
c @ datastar.js:11

I really can’t find anything in relation to doing this.

Apologies in advanced if I am missing something simple.

useEffect with const Dependency Parameters React Question?

I have this code in React:

const EditPost = ({
  posts, handleEdit, editBody, setEditBody, editTitle, setEditTitle
}) => {
    const { id } = useParams();
    const post = posts.find(post => (post.id).toString() === id);

    useEffect(() => {
        if (post) {
            setEditTitle(post.title);
            setEditBody(post.body);
        }
    }, [post, setEditTitle, setEditBody])

    return (
        <div> nothing here yet... </div>
    )
}

This example is from a youtube.com video. Why did the author put post, setEditTitle, and setEditBody variables in the dependency array? What effect does that have? Why bother even having useEffect() even at all?

This is from React JS Full Course for Beginners | Complete All-in-One Tutorial | 9 Hours
You can see the same code from:
Ch 19: Axios API Requests
6:29:42

Thanks!