Unusual Behaviour in ‘joi’ validation

I was working on a personal project and I wanted to use ‘joi’ library for validation of my request body.

import * as Joi from 'joi';

const joiSchema= Joi.object({
    ans: Joi.number().required().not(0),
}).unknown(true).keys();

const data = {
    ans: 0,
};

async function validateData() {
    try {
        const value =  await joiSchema.validateAsync(data);
        console.log('Validation succeeded:', value);
    } catch (err) {
        console.error('Validation error:', err);
    }
}

// Call the async function
validateData();

I have validation succeeded for ans:0 in this case but i have clearly mentioned that ans should not be zero , and infact the function validateData() gives validation succeeded even when i am passing string to it.

But when i remove keys() method from joiSchema I am getting the desired results.
I looked at the documentation also for keys() but could not find any satisfactory answers.

How to get the correct location of an element after scrolling to it?

I am trying to determine the position of a specific element on a webpage after scrolling to it using JavaScript.

Questions:
How can I accurately get the position of an element after scrolling to it?
Are there any common pitfalls or additional steps I should be aware of?
Any help or suggestions would be greatly appreciated!

Using getBoundingClientRect() after scrolling.
Checking position values before and after scrolling.
Ensuring no CSS transformations are affecting the element’s position.
Testing with SeleniumBase’s bounding_box() method.
Testing with Playwright to capture element positions.

chrome.downloads.download API to a specific folder

I’m trying to use an extension to download files automatically. Per chrome.downloads API it’s possible to set a folder to download the file inside a new folder inside downloads folder:

The DownloadItem’s new target DownloadItem.filename, as a path
relative to the user’s default Downloads directory, possibly
containing subdirectories
. Absolute paths, empty paths, and paths
containing back-references “..” will be ignored. filename is ignored
if there are any onDeterminingFilename listeners registered by any
extensions.

The problem is that when I try to download the file to test/filename.jpg folder, nothing happens. If I remove the folder name and let only filename.jpg it downloads as supposed to the main download folder. The following code doesn’t work:

  chrome.contextMenus.onClicked.addListener((info, tab) => {
    if (info.menuItemId === "downloadfile") {
      var bread1 = document.getElementsByClassName('c-breadcrumb__link')[1].innerHTML
      const filename = "hoge.jpg";
      const url = "image_url";
      
      chrome.downloads.download({ 
        filename: bread1 + "" + filename, 
        url: url,
        conflictAction: overwrite,
       });

    }
  });

This one works without problem:

  chrome.contextMenus.onClicked.addListener((info, tab) => {
    if (info.menuItemId === "downloadfile") {
      //var bread1 = document.getElementsByClassName('c-breadcrumb__link')[1].innerHTML
      const filename = "hoge.jpg";
      const url = "image_url";
      
      chrome.downloads.download({ 
        filename: filename, 
        url: url,
        conflictAction: overwrite,
       });

    }
  });

I want to automatically sort all the downloads within subfolders by the filename.
This does not work even if I create the folder manually.

Already tried with slash and backslash and even added a slash/backslash in the main folder also.

I know that usually, you can’t create folders with JS, but I want to test if this API can create a subfolder in Chrome “Downloads” folder, but since it doesn’t even work if I create the folder manually, it seems something went wrong.
If anyone knows that isn’t possible even using this API, what would be the best way to achieve the folder creation process automatically to sort and place the files inside their own folder?

Load Local Image using phaser js

I’m downloading some code from Rosebud AI, and when I start with their link or an external link, it works. However, when I try to use my own local storage to play the assets, it’s not working.

    this.load.audio("buttonSound", "assets/Button.mp3");
    this.load.audio("backgroundMusic", "assets/bg.mp3");
    this.load.audio("stoneDropSound", "assets/StoneDrop.mp3");

My Folder Structure
Folder Structure

How To Load it Just it is

How to get the property’s name of an object using jQuery?

this is my form:

<form id="inventoryForm" action="/ManderalMatrix/AddManderalInventory" class="reactiveToButton">
    <div class="row" style="margin-top: 18px">

        <div class="col-md-3">
            <div class="form-group">
                <label>
                    Size of punch (mm)
                    <span style="color:red">*</span>
                </label>
                <input name="PunchSize" id="PunchSize" type="text" class="form-control inventoryInput objectInput" />
            </div>
        </div>
        <div class="col-md-3">
            <div class="form-group">
                <label>
                    Shape
                    <span style="color:red">*</span>
                </label>
                <select name="ProductConfigId" id="ProductConfigId" class="form-control objectInput">
                </select>
            </div>
        </div>
        <div class="col-md-3">
            <div class="form-group">
                <label>
                    Radius of punch (mm)
                    <span style="color:red">*</span>
                </label>
                <input name="PunchRadius" id="PunchRadius" type="number" class="form-control inventoryInput objectInput" />
            </div>
        </div>
        <div class="col-md-3">
            <div class="form-group">
                <label>
                    Code
                    <span style="color:red">*</span>
                </label>
                <input name="ManderalMatrixCode" id="ManderalMatrixCode" type="number" class="form-control inventoryInput objectInput" />
            </div>
        </div>
        <div class="col-md-3">
            <div class="form-group">
                <label>
                    Quantity of upper punch
                    <span style="color:red">*</span>
                </label>
                <input name="UpperPunchQuantity" id="UpperPunchQuantity" type="number" class="form-control inventoryInput objectInput" />
            </div>
        </div>
        <div class="col-md-3">
            <div class="form-group">
                <label>
                    Quantity of die
                    <span style="color:red">*</span>
                </label>
                <input name="DieQuantity" id="DieQuantity" type="number" class="form-control inventoryInput objectInput" />
            </div>
        </div>
        <div class="col-md-3">
            <div class="form-group">
                <label>
                    Quantity of lower punch
                    <span style="color:red">*</span>
                </label>
                <input name="LowerPunchQuantity" id="LowerPunchQuantity" type="number" class="form-control inventoryInput objectInput" />
            </div>
        </div>
        <div class="col-md-3">
            <div class="form-group">
                <label>
                    Supplier
                    <span style="color:red">*</span>
                </label>
                <input name="Supplier" id="Supplier" type="text" class="form-control inventoryInput objectInput" />
            </div>
        </div>
        <div class="col-md-3">
            <div class="form-group">
                <label>
                    Manufacturer code
                    <span style="color:red">*</span>
                </label>
                <input name="ManufacturerCode" id="ManufacturerCode" type="text" class="form-control inventoryInput objectInput" />
            </div>
        </div>
        <div class="col-md-3">
            <div class="form-group">
                <label>
                    Type of die
                    <span style="color:red">*</span>
                </label>
                <select name="DieType" id="DieType" class="form-control objectInput">
                    <option value="1">B</option>
                    <option value="2">D</option>
                </select>
            </div>
        </div>
        <div class="col-md-3">
            <div class="form-group">
                <label>Location</label>
                <select name="PlanConfigId" id="PlanConfigId" class="form-control objectInput">
                </select>
            </div>
        </div>
        <div class="col-md-3">
            <div class="form-group">
                <label>Machine name</label>
                <select name="MachineId" id="MachineId" class="form-control objectInput">
                </select>
            </div>
        </div>
        <div class="col-md-3">
            <div class="form-group">
                <label>
                    Large diameter
                    <span style="color:red">*</span>
                </label>
                <input name="LargeDiameter" id="LargeDiameter" type="number" class="form-control inventoryInput objectInput" />
            </div>
        </div>
        <div class="col-md-3">
            <div class="form-group">
                <label>
                    Small diameter
                    <span style="color:red">*</span>
                </label>
                <input name="SmallDiameter" id="SmallDiameter" type="number" class="form-control inventoryInput objectInput" />
            </div>
        </div>

    </div>

</form>

I set the class ‘objectInput’ for all inputs and selects to controlling them.
I used ajax to get an object from the server and get data.
I want to check if the name of the properties of ‘data’ that returned is equal to the id of the inputs, put the value of data’s property on the input’s value

I tried this but I dont know the rest:

function UpdateInventory(id) {

    $.get("/ManderalMatrix/GetTheInventory?id=" + id, function (data) {
        $('.objectInput').each(function () {

        })
    })
}

Using local storage for boolean [duplicate]

I am creating a google extension, and I need to save booleans as a settings feature. The program unable to load the local storage after saving the values.

if ((localStorage.getItem(lightMode) === null) || (localStorage.getItem(compactMode) === null) || (localStorage.getItem(borderMode)) || (localStorage.getItem(temeplatesMode))) {
    console.log("No data found");
    var lightMode = false;
    var compactMode = true;
    var borderMode = false;
    var templatesMode = false;
  } else {
    console.log("Data found!");
    var lightMode = localStorage.getItem(lightMode);
    var compactMode = localStorage.getItem(compactMode);
    var borderMode = localStorage.getItem(borderMode);
    var templatesMode = localStorage.getItem(templatesMode);
  }


const saveButton = document.getElementById('saveButton');
saveButton.addEventListener('click', save);

function save() {
    localStorage.setItem("lightMode", lightMode);
    localStorage.setItem("compactMode", compactMode);
    localStorage.setItem("borderMode", borderMode);
    localStorage.setItem("templatesMode", templatesMode);
    console.log("lightMode:", localStorage.getItem("lightMode"));
    console.log("compactMode:", localStorage.getItem("compactMode"));
    console.log("borderMode:", localStorage.getItem("borderMode"));
    console.log("templatesMode:", localStorage.getItem("templatesMode"));
    alert("Options Saved!");
}

I tried creating a save function to set my variables in local storage, but I was unable to load the variables. Is there another solution to save my variables in local storage?

Adding each array item a className depending on the one it already has

I need to add each <span> of a group into an array which contains their specific className – For example: All spans which have className === class-A1 – into the array or object let spansA1: []/{};.

Basically each <span> will need to be added an additional class depending on the class-A${i} (class index-number) it already has – For example: span[0].className === class-A${0} would get the class with: A${0}-Enter.

I actually tried to write such function but got the error: “Not a function” – see in the code.

After that I tried using indexOf() which didn’t work either.

There obviously is a way to create that but I’m not really sure how would a professional programmer would have done it.

In the JS code I did manage to sort all spans of each paragraph into an array – as well as getting their class-names.

But the problem as I said is adding each span a specific class depending on the class-index-number it already has.

You can see in the HTML code that each span inside a paragraph has text which specifies its intended color – as well as its class-name. For example: <span class="color-A2">GREEN TOPIC</span>.

Thank you very much.

const spanBlocks = [...document.getElementsByClassName('highlight')];

console.log(`const 'spanBlocks' equals:`);
console.log(spanBlocks);
console.log('---- ---- ---- ----');

const Colors = [
    "color-A0", "color-A1", "color-A2", "color-A3",
    "color-A4", "color-A5", "color-A6", "color-A7",
];

const Entries = [
    "A0-enter", "A1-enter", "A2-enter", "A3-enter",
    "A4-enter", "A5-enter", "A6-enter", "A7-enter",
];

const Leaves = [
    "A0-leave", "A1-leave", "A2-leave", "A3-leave",
    "A4-leave", "A5-leave", "A6-leave", "A7-leave",
];

for (let i = 0; i < spanBlocks.length; i++) {
    const block = [...document.querySelectorAll(`span[id *= block-A${i}] span[class *= color-A]`)];

    for (let each of block) {
        each.onmouseover = (e) => {
            let currentBlock = e.target.parentNode;

            let spanGroup = [...currentBlock.querySelectorAll(`span[class *= color-A]`)];

            console.log(`const 'spanGroup [${i}]' equals:`);
            console.log(spanGroup);
            console.log('---- ---- ---- ----');

            let spanColors = spanGroup.filter(span => (span.className === `color-A${i}`)); // Thought it'd work for all spans one by one;

            console.log(`const 'spanColors' equals:`);
            console.log(spanColors);
            console.log('---- ---- ---- ----');

            for (let a = 0; a < spanGroup.length; a++) {
                let spanClassNames = [spanGroup[a].className];

                console.log(`const 'spanClassNames [${a}]' equals:`);
                console.log(spanClassNames);
                console.log('---- ---- ---- ----');

                // for (let all of spanClassNames) {
                //     let spanIndex = all.indexOf(a);

                //     console.log(`const 'spanIndex [${a}]' equals:`);
                //     console.log(spanIndex);
                //     console.log('---- ---- ---- ----');
                // };
            };

            for (let all of spanGroup) {
                all.classList.remove(`${Leaves[i]}`);
                all.classList.add(`${Entries[i]}`);
            };
        };

        each.onmouseout = () => {
            for (let all of block) {
                all.classList.remove(`${Entries[i]}`);
                all.classList.add(`${Leaves[i]}`);
            };
        };
    };
};

function sortClasses(span) {
    for (let i = 0; i < Colors.length; i++) {
        if (span.className === Colors[i]) {
            span[i].classList.add(`A${i}-enter`);
        };
    };
}; // Tried to call that as a function but it says: "Is not a function";
#container {
    cursor: none;
}

/* DIVIDER */

.A0-enter {
    animation: A0-enter 0.4s ease 0s 1 normal forwards;
}

@keyframes A0-enter {
    0% {
        background-color: red;
        color: black;
    }

    100% {
        background-color: red;
        color: white;
    }
}

.A0-leave {
    animation: A0-leave 0.4s ease 0s 1 normal forwards;
}

@keyframes A0-leave {
    0% {
        color: white;
        background-color: red;
    }

    100% {
        color: unset;
        background-color: unset;
    }
}

/* DIVIDER */

.A1-enter {
    animation: A1-enter 0.4s ease 0s 1 normal forwards;
}

@keyframes A1-enter {
    0% {
        background-color: blue;
        color: black;
    }

    100% {
        background-color: blue;
        color: white;
    }
}

.A1-leave {
    animation: A1-leave 0.4s ease 0s 1 normal forwards;
}

@keyframes A1-leave {
    0% {
        color: white;
        background-color: blue;
    }

    100% {
        color: unset;
        background-color: unset;
    }
}

/* DIVIDER */

.A2-enter {
    animation: A2-enter 0.4s ease 0s 1 normal forwards;
}

@keyframes A2-enter {
    0% {
        background-color: green;
        color: black;
    }

    100% {
        background-color: green;
        color: white;
    }
}

.A2-leave {
    animation: A2-leave 0.4s ease 0s 1 normal forwards;
}

@keyframes A2-leave {
    0% {
        color: white;
        background-color: green;
    }

    100% {
        color: unset;
        background-color: unset;
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>

    <style>
        body {
            display: flex;

            justify-content: center;
            padding-top: 10%;

            font-size: 40px;
        }
    </style>
    <link rel="stylesheet" href="a.css">
</head>
<body>
    <div id="container">

        <span id="block-A0" ; class="highlight">
          <p>

            <span class="color-A0">RED TOPIC</span>
            -
            <span class="color-A1">BLUE TOPIC</span>
            -
            <span class="color-A2">GREEN TOPIC</span>
            -
            <span class="color-A0">RED TOPIC</span>
            -
            <span class="color-A1">BLUE TOPIC</span>

          </p>
        </span>

        <span id="block-A1" ; class="highlight">
          <p>

            <span class="color-A1">BLUE TOPIC</span>
            -
            <span class="color-A2">GREEN TOPIC</span>
            -
            <span class="color-A2">GREEN TOPIC</span>
            -
            <span class="color-A1">BLUE TOPIC</span>
            -
            <span class="color-A0">RED TOPIC</span>

          </p>
        </span>

        <span id="block-A2" ; class="highlight">
          <p>

            <span class="color-A2">GREEN TOPIC</span>
            -
            <span class="color-A1">BLUE TOPIC</span>
            -
            <span class="color-A0">RED TOPIC</span>
            -
            <span class="color-A2">GREEN TOPIC</span>
            -
            <span class="color-A1">BLUE TOPIC</span>

          </p>
        </span>

      </div>

    <script src="a.js"></script>
</body>
</html>

Issue with contenteditable Element

Im trying to get rid of the <div><br></div> thats added to a contenteditable element after ‘enter’ is pressed on android.

I learned that if i added css white-space: pre or display: inline-block or white-space: pre-wrap to the element it would get rid of it, which it did, but not on android. Everything works just as expected on chrome windows, but on chrome android it doesn’t work at all. The <div><br></div> is still added, and what’s even weirder is that it adds two of them.

Because its on android, i have to use input events and not key events so when i tried simply replacing the added elements with n it would do even stranger things.

Does anyone have a solution to this? Ive been trying to find to a solution for literally days, and have tried what feels like everything.

How to troubleshoot this error – “Could not establish connection. Receiving end does not exist.”

I am developing a chrome extension to provide time stamps to all youtube videos, and it keeps giving me this error – “Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.”, I have just started building it,
here’s my background.js file

chrome.tabs.onUpdated.addListener((tabId, tab) => {
  if (tab.url && tab.url.includes("youtube.com/watch")) {
    const queryParameters = tab.url.split("?")[1];
    const urlParameters = new URLSearchParams(queryParameters);

    chrome.tabs.sendMessage(tabId, {
      type: "NEW",
      videoId: urlParameters.get("v"),
    });
  }
});

and here’s my contentScript.js

(() => {
    let youtubeLeftControls, youtubePlayer;
    let currentVideo = "";

    chrome.runtime.onMessage.addListener((obj, sender, response) => {
        const {type, value, videoId} = obj;
        if(type === "NEW")
        {
            currentVideo = videoId;
            newVideoLoaded();
        }
    });
    
}) ();

and lastly my manifest.json

{
    "name": "YT Saver",
    "version": "0.1.0",
    "description": "Saving timestamps in YT videos",
    "permissions": ["storage", "tabs"],
    "host_permissions": ["https://*.youtube.com/*"],
    "background": {
      "service_worker": "background.js"
    },
    "content_scripts": [
      {
        "matches": ["https://*.youtube.com/*"],
        "js": ["contentScript.js"]
      }
    ],
    "web_accessible_resources": [
      {
        "resources": [
          "assets/bookmark.png",
          "assets/play.png",
          "assets/delete.png",
          "assets/save.png"
        ],
        "matches": ["https://*.youtube.com/*"]
      }
    ],
    "action": {
      "default_icon": {
        "16": "assets/ext-icon.png",
        "24": "assets/ext-icon.png",
        "32": "assets/ext-icon.png"
      },
      "default_title": "YT Saver",
      "default_popup": "popup.html"
    },
    "manifest_version": 3
}

I tried to make sure I was linking my content scripts correctly in manifest.json file, I reloaded the chrome extension page and the files, I have tried deleting the entire package, reloading it. It did not make a difference yet. I have tried approaches from other posts, but none have worked yet. Any suggestions would be helpful thanks!

useLoaderdata gives error ‘useLoaderData must be used within a data router’ in react

I am trying to load API from the routes using loader, params, and useLoaderData hook.

I used loader params in my existing routing structure and useLoaderData hook in my component but it didn’t work.
I checked other questions, but they primarily work on single component routing structure, but for me routing for all components are already done. How can I modify my router accordingly?

<BrowserRouter>
  <Header />
  <Routes>
    <Route path='/' element={<Home />} />
    <Route path='/about' element={<About />} />
    <Route path='/services' element={<Services />} >
      <Route element={<WebServices />} index />
      <Route path='web' element={<WebServices />} />
      <Route path='app' element={<AppServices />} />
      <Route path='cloud' element={<CloudServices />} />
    </Route>
    <Route path='/blog' element={<Blog />} loader={fetchPosts} />
    <Route path='*' element={<Page404 />} />
  </Routes>
</BrowserRouter>
function Blog(props) {
  const list = useLoaderData();

  return (
    <div className='blog-container'>
      <div className='container'>
        <h1>Your Blog comes here</h1>
      </div>
      <div className='blog-post-container'>
        {list && list.length > 0
          ? list.map((item, index) => {
            return (
              <div className='blog-card'></div>
            )
          }) : <p>No post found</p>
        }
      </div>
    </div>
  )
}

How to implement auto scroll in a div when the user has typed the text which fits in it?

I am building a typing test webapp with ReactJS and currently I am stuck on implementing auto scroll.
In my react code, I have a state variable named ‘typedText’ which contains the currently typed text by the user. The full text to be typed is stored in a state array ‘allTexts’ which contains all paragraphs and the current paragraph is located with a ‘currentTextIndex’

   const [allTexts, setAllTexts] = useState([
   {title: 'Demo', text: "One of you must come here"}
   ])
   const [currentTextIndex,setCurrentTextIndex] = useState(0);
   const [typedText, setTypedText] = useState('');
   const [invalidKeys, setInvalidKeys] =             useState(['Shift','Control','Alt','CapsLock','Backspace','Tab'])

   function keyDownHandler(e){ //This function updated the typed text
   e.preventDefault();
   
   if(!startTime && !(invalidKeys.includes(e.key))){ //Starting the timer if the user has pressed  a valid key and the timer is not already started
     let dtObj = new Date();
     setStartTime(dtObj.getTime());
   }


   if(invalidKeys.includes(e.key)){ //If user types invalid key, then check if it is backspace,
   //and perform backspace operation if it is allowed in configuration 
     if(e.key === 'Backspace' && config.backspaceAllowed && startTime && typedText.length>0){
       let typedTextCopy = typedText.slice(0,typedText.length-1);
       setTypedText(typedTextCopy);
     }
   } else { //Otherwise, simply append the typed key into the typedText
       let typedTextCopy = typedText + e.key;
       setTypedText(typedTextCopy);
   }

The text on the screen is displayed in a simple div and not in a HTML Input as below –

    import React from 'react'

  export default function TextDisplay({givenText,typedText}) {
  let typedArray = typedText.split('');
  let givenArray = givenText.split('');
  return (
      <div className='text-justify w-4/5 sm:w-3/5 text-base sm:text-lg md:text-xl lg:text-2xl h-full overflow-y-auto p-1'>
          {givenArray.map((val, ind) => {
              if (val == typedArray[ind] && ind < typedArray.length) { //Characters which are correctly been typed
                //spans cannot be used dur to certain problems with them, so we will use divs with inline display to animate the cursor border properly
                  return <div key={ind} className={`${ind === typedArray.length - 1 ? 'border-r-2' : ''} ${typedArray.length === 0 && ind === 0? 'border-l-2' : ''} character inline border-purple-500 text-purple-700`}>{val}</div>
                } else if(val !== typedArray[ind] && ind < typedArray.length){ //Characters which have been typed incorrectly
                  return <div key={ind} className={`${ind === typedArray.length - 1 ? 'border-r-2' : ''} ${typedArray.length === 0 && ind === 0? 'border-l-2' : ''} character inline border-purple-500 ${val===' '?'underline decoration-red-500':'text-red-500'}`}>{val}</div>
              } else { //Characters not typed yet
                  return <div key={ind} className={`${ind === typedArray.length - 1 ? 'border-r-2' : ''} ${typedArray.length === 0 && ind === 0? 'border-l-2' : ''} character inline border-purple-500 text-slate-400`}>{val}</div>
              }
          })}
          

      </div>
  )
}

Here is the url of website – https://shubhamsharma64337.github.io/simpletype/

Link to repo – https://github.com/ShubhamSharma64337/simpletype

How do I implement auto scroll such that when the paragraph is large, and the user reaches the end of the visible text, the div is scrolled automatically?

I tried to think of splitting the paragraph into multiple parts of smaller length which does not need to be scrolled, and simply replacing the current part with next part once the user finishes one part by checking the length of text typed by the user and comparing it with the length of the part. But I think that there must be a better way to do this.

Route.get() requires a callback function but got a [object Promise]

I’m trying to call two middlewares in chain. The first one will passa a parameter to controller and second one doesn’t require it.

Following is my code –
routes.js

module.exports = (app) => {
app.get('/printrajesh',
        AuthController.checkauthorization('xyz'),
        RmController.printrajesh
    )
}

The Authcontroller

module.exports = {
async checkauthorization (role){
        console.log("Check Authorization is called")
        console.log(role)

        return function(req, res, next){
            if(role != 'xyz'){
                res.status(400).send({
                    error: 'You are not Authorized'
                })
            }else{
                next()
            }
        }
        
    }
}

The error I’m getting is –

Server is Up and Running...
Check Authorization is called
xyz
/home/tanmay/gmphbackend/node_modules/express/lib/router/route.js:211
        throw new Error(msg);
        ^

Error: Route.get() requires a callback function but got a [object Promise]
    at Route.<computed> [as get] (/home/tanmay/gmphbackend/node_modules/express/lib/router/route.js:211:15)
    at app.<computed> [as get] (/home/tanmay/gmphbackend/node_modules/express/lib/application.js:499:19)
    at module.exports (/home/tanmay/gmphbackend/src/routes.js:19:9)
    at Object.<anonymous> (/home/tanmay/gmphbackend/src/app.js:14:20)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Module._load (node:internal/modules/cjs/loader:960:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:23:47

Node.js v18.16.1

Not Sure what I am doing wrong here. Please help. Thanks

JS for CSS image slider box

I am finding an image box: preview and small preview list under the preview.

My expected result is as follow :

The html is as follow :

 <!--image list-->
        <div class="image-list-container d-flex">
          <div class="image-list-item cursor-pointer image-highlight">
            <div id="" class="">
              <div class="hv-centered"><!----><img class="show-img img-fluid" src="https://5.imimg.com/data5/NR/TP/MY-9295383/hcl-desktop-500x500.jpg" alt="" /></div>
            </div>
          </div>
          <div class="image-list-item cursor-pointer" >
            <div id="" class="">
              <div class="hv-centered"><!----><img class="show-img img-fluid" src="https://tiimg.tistatic.com/fp/1/007/341/shock-proof-black-color-medium-size-acer-desktop-computer--825.jpg" alt="" /></div>
            </div>
          </div>
          <div class="image-list-item cursor-pointer" >
            <div id="" class="">
              <div class="hv-centered"><!----><img class="show-img img-fluid" src="https://cdn.britannica.com/97/155497-050-4C5BFFFC/laptop-computer.jpg" alt="" /></div>
            </div>
          </div>
          <!---->
          <div class="image-list-item cursor-pointer add-image-section add-download-img p-0">
            <div id="ember519" class="dropdown btn-group h-100">
              <button class="btn file-upload add-download-img-btn" type="button">
                <input id="add-images-btn" title="" multiple="" accept="image/gif,image/jpeg,image/png,image/bmp,image/jpg" class="upload form-control cursor-pointer" type="file" />
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="icon align-text-top action-icons icon-xlg fill-dropdown-blue">
                  <path d="M256 15C122.9 15 15 122.9 15 256s107.9 241 241 241 241-107.9 241-241S389.1 15 256 15zm122 263H278v100c0 12.2-9.8 22-22 22s-22-9.8-22-22V278H134c-12.2 0-22-9.8-22-22s9.8-22 22-22h100V134c0-12.2 9.8-22 22-22s22 9.8 22 22v100h100c12.2 0 22 9.8 22 22s-9.8 22-22 22z"></path>
                  <path fill="#FFF" d="M378 234H278V134c0-12.2-9.8-22-22-22s-22 9.8-22 22v100H134c-12.2 0-22 9.8-22 22s9.8 22 22 22h100v100c0 12.2 9.8 22 22 22s22-9.8 22-22V278h100c12.2 0 22-9.8 22-22s-9.8-22-22-22z"></path>
                </svg>
              </button>
              <button id="ember521" class="dropdown-toggle btn btn-secondary rounded-start-0 add-download-img-btn no-border" type="button"></button>
              <div class="dropdown-menu dropdown-menu-right">
                <button class="dropdown-item file-upload">
                  <input id="ember522" title="" multiple="" accept="image/gif,image/jpeg,image/png,image/bmp,image/jpg" class="upload form-control cursor-pointer" type="file" />
                  Add More Images
                </button>
                <button class="dropdown-item" data-ember-action="" data-ember-action-523="523">Download As ZIP</button>
              </div>
            </div>
          </div>
        </div>
        <!--/-->

I am still learning js in how to have the scenario, when each item list is clicked it will previewed in the box above. as well when the primary text is clicked.

the code is here text

Thank you for you help.

How to pass Cache-control in RTC query in get request?

I recently started learning RTK Query and I’m now studying how to work with caching. Could someone please suggest the best way to send the Cache-Control header in a request? I’ve seen the following approach in the web, and I’d like to know if it’s correct.

const exampleApi = createApi({
  reducerPath: 'exampleApi',
  baseQuery: fetchBaseQuery({
    baseUrl: '/api',
  }),
  endpoints: (builder) => ({
    getExample: builder.query({
      query: () => ({
        url: '/example',
        headers: {
          'Cache-Control': 'no-cache',
        },
      }),
    }),
  }),
})

I haven’t tried many options yet, I only found this one, I’m not entirely sure it’s the right one.