How to make a carousel to be infinite in a smooth manner

I’m working on this React x Motion carousel that brings a card to the center of the screen when it has been clicked, depending on its index. However, I also want an added function to make the cards to carousel to be infinite.

import { motion } from "motion/react";
import { useState } from "react";

const carouselImages = [
  "../img-11.jpg",
  "../img-2.jpg",
  "../img-13.jpg",
  "../img-4.jpg",
  "../img-15.jpg",
  "../img-1.jpg",
  "../img-19.jpg",
  "../img-3.jpg",
  "../img-14.jpg",
  "../img-5.jpg",
];

export default function StaggerCarousel() {
  const [images, setImages] = useState(carouselImages);
  const [selectedIndex, setSelectedIndex] = useState(0);

  let itemWidth;

  if (window.innerWidth > 768) {
    itemWidth = 200 + 20;
  } else {
    itemWidth = 100 + 20;
  }

  const handleOnClick = (index) => {
    const clicked = images[index];
    const updated = [...images, clicked];
    setImages(updated);
    setSelectedIndex(index);
  };
  return (
    <div className="carousel-container w-screen h-screen flex items-center justify-center bg-gray-900">
      <motion.ul className="carousel-list relative overflow-hidden h-[500px] min-w-[300px] md:min-w-[700px]">
        {images.map((img, index) => {
          return (
            <motion.li
              key={index}
              className="carousel-item w-[100px] md:w-[200px] h-48 rounded-lg absolute left-1/2 top-1/2 cursor-pointer transform -translate-x-1/2 -translate-y-1/2"
              animate={{
                translateX: (index - selectedIndex) * itemWidth,
                y: -50 + (selectedIndex === index ? -20 : 10),
                rotate: selectedIndex === index ? 0 : 5,
                opacity: selectedIndex === index ? 1 : 0.5,
                transition: {
                  duration: 0.3,
                  type: "spring",
                  stiffness: 100,
                },
              }}
              style={{
                backgroundImage: `url(${img})`,
                backgroundSize: "cover",
                backgroundPosition: "center",
           
              }}
              onClick={() => handleOnClick(index)}
            ></motion.li>
          );
        })}
      </motion.ul>
    </div>
  );
}

The function above seems to work. But it has two flaws.
The first is I can actually see the cards flying across the screen to the end of the carousel. Second is that clicking the same image also appends the card to the end of the carousel.

I don’t understand the syntax of this type declaration in TypeScript [closed]

Can someone explain what is happening here? I think it is mandating SnackbarContentCallback must be of type React.ReactNode or a function that accepts two arguments of SnackbarKey and (optionally) of SnackbarMessage type,and it must return a React.ReactNode.

  1. Please someone tell me if I am correct or, if I am wrong, what it’s actually doing.
  2. Please tell me why there is a leading pipe after the =.
export type SnackbarContentCallback =
    | React.ReactNode
    | ((key: SnackbarKey, message?: SnackbarMessage) => React.ReactNode);

onKeyDown event doesn’t triggers on Enter

In my React Typescript app I have an input and I want this input to update search on Enter key down. My code:

<SearchInput
                    placeholder={formatMessage('SV_UNIT_LIST_SEARCH_PLACEHOLDER')}
                    value={searchState.searchText}
                    onChange={(event) => {
                      const inputValue = (event.target as unknown as HTMLInputElement).value;
                      searchText = inputValue;
                      if (inputValue === '') {
                        dispatchSearch(updateSearch({ newSearch: searchText }));
                      }
                    }}
                    onKeyDown={(event) => {
                      console.log(event.key);
                      if (event.key === 'Enter') {
                        dispatchSearch(updateSearch({ newSearch: searchText }));
                      }
                    }}
                  />

In the console I’m getting all pressed keys but when I hit Enter just nothing happens.
What is the problem with this code? Thank you!

enter image description here

How to modify Widget iframe background to transparent?

I’ve embedded the Freshdesk help widget into my app, which supports both light and dark themes. In dark mode, the widget appears with a white boxed background (see the image). In light mode, the background appears transparent and looks great. I think is some kind of error.

Freshdesk widget

<script>
  window.fwSettings = {
    widget_id: 1234567890 // Replace with your actual widget ID
  };

  (function() {
    if (typeof window.FreshworksWidget !== "function") {
      var n = function() { n.q.push(arguments); };
      n.q = [];
      window.FreshworksWidget = n;
    }
  })();
</script>

<script type="text/javascript" src="https://euc-widget.freshworks.com/widgets/1234567890.js" async defer></script>

Do you have any idea how can i modifiy the background in an iframe? because everyithing ive tried doendt work

How to bypass or auto-accept Chrome’s file editing permission dialog triggered by window.showDirectoryPicker() in Playwright?

I trying to download a file into a folder that is not in the list of managed permissions of Playwright.

The app that I am testing opens the windows file choose with the window.showDirectoryPicker() JS method, then with (Autoit) I select the folder in the file explorer window and click on “Select Folder” button, after that in the browser a permission dialog is triggered asking the user for file editing permission. I am not able to click on the “Edit files” button with Playwright. This is what the dialog looks like:

enter image description here

This is an example of what my app do, I want to download into a folder in my machine during my playwrite tests.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Create and Save File in Directory</title>
</head>
<body>
  <h1>Create and Save File in Directory</h1>
  <p>Click the button below to select a directory and save a file directly to it.</p>
  <button id="saveFileButton">Save File</button>

  <script>
    document.getElementById("saveFileButton").addEventListener("click", async () => {
      try {
        // Open the directory picker
        const directoryHandle = await window.showDirectoryPicker({mode: "readwrite"});

        // Create a new file in the selected directory
        const fileHandle = await directoryHandle.getFileHandle("test-file.txt", {
          create: true, // Create the file if it doesn't exist
        });

        // Create a writable stream to write to the file
        const writable = await fileHandle.createWritable();

        // Write some content to the file
        await writable.write("This is a test file created and saved in the selected directory.");

        // Close the writable stream
        await writable.close();

        alert("File saved successfully in the selected directory!");
      } catch (error) {
        console.error("Error saving file:", error);
        alert("An error occurred while saving the file.");
      }
    });
  </script>
</body>
</html>

This is the code that will test the above page

package com.example.demo;

import com.microsoft.playwright.*;

import org.junit.jupiter.api.*;


public class TestExample {
    static Playwright playwright;
    static Browser browser;
    BrowserContext context;
    Page page;

    @BeforeAll
    static void setupClass() {
        playwright = Playwright.create();
        browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false));
    }

    @AfterAll
    static void tearDownClass() {
        browser.close();
        playwright.close();
    }

    @BeforeEach
    void setup() {
        context = browser.newContext();
        page = context.newPage();
    }

    @AfterEach
    void tearDown() {
        context.close();
    }

    @Test
    void testSaveFileWithAutoIt() throws Exception {
        // Navigate to your HTML file
        page.navigate("file:///C:/path/test-save-with-picker.html");


        // Listen for the alert dialog of file saved sucessfully
        page.onceDialog(dialog -> {
            System.out.println("Dialog message: " + dialog.message());
            dialog.accept();
        });



        // Run the AutoIt script to set the file download path
        Process process = Runtime.getRuntime().exec("C:\autoit\set-file-download-path.exe");
        page.waitForTimeout(3000);

        // Click the button to open the directory picker
        page.click("#saveFileButton");
        page.waitForTimeout(20000);

        int exitCode = process.waitFor(); // Wait for the AutoIt script to complete
        if (exitCode == 0) {
            System.out.println("AutoIt script executed successfully.");
        } else {
            System.out.println("AutoIt script failed with exit code: " + exitCode);
        }

        // I need to auto accept the permission dialog here <========


        //Check if the file was created in C:TestDirectory
        java.nio.file.Path filePath = java.nio.file.Paths.get("C:\TestDirectory");
        Assertions.assertTrue(java.nio.file.Files.exists(filePath), "File was not created!");

    }
}

And the Autoit script

WinWaitActive("Select where this site can save changes")
ControlSetText("Select where this site can save changes", "","Edit1",  "C:TestDirectory")
Sleep(1000)
ControlClick("Select where this site can save changes", "Select Folder", "Button1")

confusion between import in NestJS with global module implementation

I have a confusion regarding the implementation of a global module in NestJS, and the import of a shared service

I’m following this guide: NestJS- Global Modules

and this is what I have so far:
shared.service:

import { Injectable } from '@nestjs/common';

@Injectable()
export class SharedService {
  async catchError<T>(promise: Promise<T>): Promise<[undefined, T] | [Error]> {
    return promise
      .then((data): [undefined, T] => {
        return [undefined, data]}
      )
      .catch((error): [Error] => {
        console.error('Error:', error);
        return [error];
      });
    }
}

shared.module:

import { Module, Global } from '@nestjs/common';
import { SharedService } from './shared.service';

@Global()
@Module({
  providers: [SharedService],
  exports: [SharedService],
})
export class SharedModule {}

the app.module:

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { AppController } from './app.controller';
import { MongooseModule } from '@nestjs/mongoose';
import { AppService } from './app.service';
import { PersonsModule } from './persons/persons.module';
import { SharedModule } from './shared/shared.module';


@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    MongooseModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => ({
        uri: configService.get<string>('MONGODB_URI'),
      }),
      inject: [ConfigService],
    }),
    PersonsModule,
    SharedModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

and this is my implementation on the persons.service:

import { Inject, Injectable, InternalServerErrorException } from '@nestjs/common';
import { CreatePersonDto } from './dto/create-person.dto';
import { UpdatePersonDto } from './dto/update-person.dto';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { Person } from './persons.schema';
import { SharedService } from 'src/shared/shared.service';

@Injectable()
export class PersonsService {
  constructor(
     private readonly sharedService: SharedService,
    @InjectModel('Person') private readonly personModel: Model<Person>,
  ) {}

  create(createPersonDto: CreatePersonDto) {
    return 'This action adds a new person';
  }

  async findAll(): Promise<Person[]> {
    const [error, data] = await this.sharedService.catchError(
      this.personModel.find().exec()
    );

    if (error || !data) {
      throw new InternalServerErrorException('Error fetching persons');
    }

    return data;
  }

  async findOne(guid: string) {
    const [error, data] = await this.sharedService.catchError(
      this.personModel.findOne({guid}).exec()
    );

    if (error || !data) {
      throw new InternalServerErrorException('Error fetching person');
    }

    return data;
  }

  update(id: number, updatePersonDto: UpdatePersonDto) {
    return `This action updates a #${id} person`;
  }

  remove(id: number) {
    return `This action removes a #${id} person`;
  }
}

And this is where the confusion comes in, if I’m making a global module…
why do I need to make this import on the persons.service above ?

import { SharedService } from 'src/shared/shared.service';

and… if I have to make that import, what’s the point of a global module ?, I mean… if I have to make that import anyways, what’s the point of the global module ?

When using ctx.moveTo() with Html Canvas Tag ctx.arc(), moveTo() draws a line

For the purpose of improving myself and because I was bored, I was learning the canvas tags in html by following the doc of mozilla and we were drawing a face there. I tried to make the face as given by mozilla, but lines appeared on my face due to the values and I don’t know why.

<body>
    <canvas class="canvas" width="150" height="150"></canvas>
</body>
<script>
        const canvas = document.querySelector(".canvas");
        const ctx = canvas.getContext("2d")

        ctx.beginPath()
        ctx.arc(75, 75, 60, 0, Math.PI * 2, true)
        ctx.moveTo(40, 40)
        ctx.arc(50, 50, 10, 0, Math.PI * 2, true)
        ctx.moveTo(60, 50)
        ctx.arc(100, 50, 10, 0, Math.PI * 2, true)
        ctx.moveTo(110, 110)
        ctx.arc(80, 110, 30, 0, Math.PI, true)
        ctx.stroke()
</script>

Expected face:

expected face screenshot

Result face:

result face

As you can see, I’m talking about unwanted lines on the face.

All I know and discovered is that for some reason the x value of the moveTo should be as much as the radius of the circle and the y values should be the same – but I don’t know why. I wanted to ask you why this is the case.

In summary, I haven’t figured out why, but for some reason, when I play with the values or when I make the values incompatible, a line appears.

Code

Why isn’t my JavaScript form validation working properly or hiding the form after submit?

I’m trying to validate a shipping form using JavaScript. If both the name and postal code fields are filled, it should hide the form and display a thank you message with the user’s name and postal code.

However, when I click the submit button:

  • The validation doesn’t seem to trigger correctly.

  • Sometimes I get errors in the browser console.

  • The form doesn’t hide after submission.

    I’m trying to validate a shipping form using JavaScript. If both the name and postal code fields are filled, it should hide the form and display a thank you message with the user’s name and postal code.

However, when I click the submit button:

The validation doesn’t seem to trigger correctly.

Sometimes I get errors in the browser console.

The form doesn’t hide after submission.

window.onload = function () { var postalCode = document.getElementById(“thanksPC”); var thanksMessage = document.getElementById(“thanks_msg”); var customerName = document.getElementById(“thanksCustomer”); var form = document.getElementById(“shippingForm”);

Google Maps API Marker Clusterer show a dot instead of the numbers of markers inside the cluster using nextjs

I’m trying to do make a map with some POI and everything works fine except when I want to add a Marker Clusterer. In fact, I can see the cluster and interact with it, but instead of showing the number of makers inside the clusterer, it just shows a dot… Image of my current webapp.

I think the problems is here because I’m using JS instead of TS. So I tried to modify the code in the tutorial of google maps (https://developers.google.com/codelabs/maps-platform/maps-platform-101-react-js#0) but I may have made a mistake…

Also, here’s my code:

import {
  APIProvider,
  Map,
  AdvancedMarker,
  Pin,
  useMap,
} from "@vis.gl/react-google-maps";
import { MarkerClusterer, ClusterIconStyle } from "@googlemaps/markerclusterer";

export default function MapInterface({ setTableView }) {
  //------------- POLYGONS DATA -------------
  const encode = require("geojson-polyline").encode;
  const regSimpData = regSimp.features;
  const encodedRegSimp = regSimpData.map((reg) => encode(reg.geometry));

  const tableButtonClickHandler = () => {
    setTableView(true);
  };

  //------------- DATA -------------

  const initialData = [
    { key: "operaHouse", location: { lat: -33.8567844, lng: 151.213108 } },
    { key: "tarongaZoo", location: { lat: -33.8472767, lng: 151.2188164 } },
    { key: "manlyBeach", location: { lat: -33.8209738, lng: 151.2563253 } },
    { key: "hyderPark", location: { lat: -33.8690081, lng: 151.2052393 } },
    { key: "theRocks", location: { lat: -33.8587568, lng: 151.2058246 } },
    { key: "circularQuay", location: { lat: -33.858761, lng: 151.2055688 } },
    { key: "harbourBridge", location: { lat: -33.852228, lng: 151.2038374 } },
    { key: "kingsCross", location: { lat: -33.8737375, lng: 151.222569 } },
    { key: "botanicGardens", location: { lat: -33.864167, lng: 151.216387 } },
    { key: "museumOfSydney", location: { lat: -33.8636005, lng: 151.2092542 } },
    { key: "maritimeMuseum", location: { lat: -33.869395, lng: 151.198648 } },
    {
      key: "kingStreetWharf",
      location: { lat: -33.8665445, lng: 151.1989808 },
    },
    { key: "aquarium", location: { lat: -33.869627, lng: 151.202146 } },
    { key: "darlingHarbour", location: { lat: -33.87488, lng: 151.1987113 } },
    { key: "barangaroo", location: { lat: -33.8605523, lng: 151.1972205 } },
  ];

  //------------- MARKERS -------------
  const BordeauxMarkers = ({ pois }) => {
    const map = useMap();
    const [markers, setMarkers] = useState({});
    const clusterer = useRef(null);

    // Initialize MarkerClusterer, if the map has changed
    useEffect(() => {
      if (!map) return;
      if (!clusterer.current) {
        clusterer.current = new MarkerClusterer({
          map: map,
        });
      }
    }, [map]);

    // Update markers, if the markers array has changed
    useEffect(() => {
      if (!clusterer.current) return;
      clusterer.current.clearMarkers();
      clusterer.current.addMarkers(Object.values(markers));
    }, [markers]);

    const setMarkerRef = (marker, key) => {
      if (marker && markers[key]) return;
      if (!marker && !markers[key]) return;

      setMarkers((prev) => {
        if (marker) {
          return { ...prev, [key]: marker };
        } else {
          const newMarkers = { ...prev };
          delete newMarkers[key];
          return newMarkers;
        }
      });
    };

    console.log(markers);

    return (
      <>
        {pois.map((poi) => (
          <AdvancedMarker
            key={poi.key}
            position={poi.location}
            ref={(marker) => setMarkerRef(marker, poi.key)}
          >
            <Pin
              background={"#FBBC04"}
              glyphColor={"#000"}
              borderColor={"#000"}
            />
          </AdvancedMarker>
        ))}
      </>
    );
  };

  //------------- CLUSTERS -------------

  return (
    <>
      <Flex position={"relative"} bgColor={"transparent"}>
        <Flex h="850px" w="vw" position={"absolute"} top={0} left={0}>
          <APIProvider
            apiKey={"APIKEY"}
            onLoad={() => console.log("Maps API has loaded.")}
          >
            <Map
              defaultZoom={6}
              defaultCenter={{ lat: 46.757285, lng: 2.2329292 }}
              mapId="MAP ID"
              onCameraChanged={(ev) =>
                console.log(
                  "camera changed:",
                  ev.detail.center,
                  "zoom:",
                  ev.detail.zoom
                )
              }
            >
              <BordeauxMarkers pois={initialData} />
              <Polygon encodedPaths={encodedRegSimp[0].coordinates} />
              <Polygon encodedPaths={encodedRegSimp[1].coordinates} />
              <Polygon encodedPaths={encodedRegSimp[2].coordinates} />
              <Polygon encodedPaths={encodedRegSimp[3].coordinates} />
              <Polygon encodedPaths={encodedRegSimp[4].coordinates} />
              <Polygon encodedPaths={encodedRegSimp[5].coordinates} />
              <Polygon encodedPaths={encodedRegSimp[6].coordinates[0]} />
              <Polygon encodedPaths={encodedRegSimp[7].coordinates[0]} />
              <Polygon encodedPaths={encodedRegSimp[8].coordinates[0]} />
              <Polygon encodedPaths={encodedRegSimp[9].coordinates[0]} />
              <Polygon encodedPaths={encodedRegSimp[10].coordinates} />
              <Polygon encodedPaths={encodedRegSimp[11].coordinates[0]} />
              <Polygon encodedPaths={encodedRegSimp[12].coordinates} />
            </Map>
          </APIProvider>
        </Flex>
        <Flex w="80%"></Flex>
        <Flex justifyContent={"end"} w="full" marginX="2%" marginY="2%">
          <Group attached={true}>
            <Button variant={"solid"} onClick={tableButtonClickHandler}>
              Table
            </Button>
            <Button variant={"solid"} disabled>
              Map
            </Button>
          </Group>
        </Flex>
      </Flex>
    </>
  );
}

I don’t really don’t know what’s wrong because my code seems the same as the one in the tutorial, except it’s in JS. I tried to modify the render but it didn’t change anything and I have watch other tutorials but that didn’t help me. Also, I didn’t really get how the ref tag works in the AdvancedMarker component…

Thanks in advance!

How to remove text from all pages of a specific website? [closed]

I’m looking for a way to remove a portion of text that appears on all page of a website.

The text i would like to remove is within a structure like this :

<div class="feedback">
    <div class="i_element">Here it is : lorem ipsum sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam ...
    </div>
</div>

I would like to remove the “Here it is :” part and leave the rest of the text everytime i load a page on this website.

I thought maybe it can be done by targetting the .i_element nested inside the .feedback div and erasing the first twelve characters of the text within the i_element div

I looked for solution and it seems that this can be achieved using tools like tampermonkey or Greasemonkey but i don’t know javascript.
I only know html and css.

I’m using Firefox.

Is this a good solution ?
Can anyone help with this ?
Thanks

Why does my resetChallenge() function not completely reset the progress and badges in my JS web app?

I’m building a small web-based challenge tracker using JavaScript and localStorage. Everything works fine, except for the resetChallenge() functionality.

When I reach 100% progress on a task, I call resetChallenge() to clear the UI and start fresh. However, while the progress bar and challenge info reset visually, the badges from the previous challenge still appear on refresh or after reset.

Here’s my resetChallenge() function:

function resetChallenge() {
    challengeTitle.textContent = "Challenge not set";
    challengeDescription.textContent = "Set your challenge above";
    progressFill.style.width = '0%';
    progressText.textContent = '0%';
    badgeContainer.innerHTML = '';
    challengeCompleted = false;
    updateProgress(0);
    localStorage.removeItem('spendSmartState');
}

The issue is that when I refresh the page, the badges come back. It seems like they’re being reloaded from localStorage inside my loadBadges() function. I suspect it’s because I’m not resetting badgesEarned, which is a global variable used to track how many badges a user has unlocked.

My init() function looks like this:

function init() {
    const savedState = JSON.parse(localStorage.getItem('spendSmartState'));
    if (savedState) {
        challengeCompleted = savedState.challengeCompleted;
        updateProgress(savedState.progress || 0);
        loadBadges(savedState.badgesEarned || 0);
    }
}

I want to:

  1. Ensure resetChallenge() properly clears everything so the user starts fresh.
  2. Optionally, provide a “hard reset” on refresh if needed, without reloading old state from localStorage.

Is resetting badgesEarned = 0 inside resetChallenge() the correct approach? Should I clear localStorage differently to avoid reloading outdated badge data?

Any advice on best practices for managing localStorage state resets and UI sync would be greatly appreciated!

Is possible to upload chunked files one by one – multiple selection in – pure JS?

I am trying to use pure JS for select multiple files on form, take one by one , chunk it and process it by PHP on server side. BUT with follow code I am not able process files one by one and also final size of files bigger than 2MB is incorrect.
My code https://pastebin.com/nmkYB3LL

I do not want to use third party products.
I really must use chunked files due used hardware.

Can somebody help me?

I tried it in many ways but without success.

New tab not focused on window.open & I don’t know why

I have an element that I’d like to be treated as if it were a link. This includes opening the target in a new tab if the user middle-clicks it (by default middle-clicking allows you to scroll the page by moving your mouse, assuming the page is larger than your window).

I can get the target to open in a new tab, but when it does the existing tab keeps the focus (unlike when you middle-click a link) & I cannot figure out why. The JS I’m using is as follows:

var list = document.getElementsByClassName('test');                 
for (let item of list) {
    item.addEventListener("mousedown", function(event) {                        
        if (event.which === 2) {                            
            event.preventDefault();                         
        }
    });                 
    item.addEventListener("auxclick", function(event) {                     
        if (event.button === 1) {                           
            event.preventDefault();
            window.open(item.getAttribute('data-href'), '_blank').focus();
        }                   
    });                 
}

… and the sample HTML that shows the behavior (in my app I’m working with table rows, but the end result is the same) is:

<span class='test' data-href='https://www.google.com'>TEST</span>

… I thought adding .focus() onto the end of the window.open() call would do what I wanted it to, but apparently not …

Same behavior seen in latest builds of Chrome, Edge, and FireFox.

To be clear, the following results with the desired behavior, but on a ‘normal’ click:

    item.addEventListener("click", function(event) {                        
        window.open(item.getAttribute('data-href'), '_blank').focus();
    }); 

Data from within JSON Array not showing when Fetching in Alpine.js

I am trying to fetch data from a (local) JSON file. I have no trouble accessing the first level of data within the JSON file (e.g. id, title, ingredients as a whole). However, the issue arises when I try to access/read/fetch the single ingredients.

By my understanding, x-for="ingredient in data.recipies.ingredients" should give me one instance of <p>TEST</p> for each ingredient per recipe. However, the output is empty. I am getting no console errors.

HTML/Alpine Markup:

<div x-data="data()">
  <template x-for="recipe in data.recipies">
    <div>
      <h3 x-text="recipe.title"></h3>
      <template x-for="ingredient in data.recipes.ingredients">
        <p>TEST</p>
      </template>
    </div>
  </template>
</div>

The JS file:

const data = () => {
    return {
        data: {
            recipies: [],
        },
        init() {
            fetch('src/recipies.json')
                .then((res) => {
                    return res.json();
                })
                .then((data) => {
                    this.data.recipies = Object.values(data)
                });
        },
    };
};

The JSON file:

{
    "aglioolio": {
        "id": 1,
        "title": "Aglio Olio + Chili",
        "ingredients": ["Spaghetti", "Olive oil", "Garlic", "Chili"]
    },
    "tortellinisoup": {
        "id": 2,
        "title": "Tortellini Soup",
        "ingredients": ["Tortellini", "Veggie Broth", "Chieves"]
    }
}

Why the check Number(undefined) === NaN fails? [duplicate]

Can anyone explain this:

{25 Apr 20:15}~ ➭ node                   
Welcome to Node.js v20.18.2.
Type ".help" for more information.
> +undefined
NaN
> NaN
NaN
> +undefined === NaN
false
> Number(undefined) == NaN
false

Even though Number(undefined) is NaN (not a number). But when i compare it with NaN it fails. Both using == and === operators.