How to change the color of the active menuitem?

I want to change the color of the selected tab in main menu or navbar when a user is on a page within that dropdown menu.This picture shows the Main Menu

This main menu has a few drop down menus that redirect the user to a page when they select one of the options.

My end Goal is to get it highlighted like this if i am on a page in this dropdown menu like the picture below I figure i will need some javascript. Just not sure how to approach it.

enter image description here

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Active Menu with Submenu</title>
    <style>
        /* Main Menu Styles */
        .menu {
            list-style: none;
            padding: 0;
            margin: 0;
            display: flex;
            background-color: #f0f0f0;
        }

        .menu-item {
            position: relative;
            margin-right: 20px;
        }

        .menu-item a {
            text-decoration: none;
            color: #333;
            padding: 10px 15px;
            display: block;
            transition: background-color 0.3s, color 0.3s;
        }

        /* Hover Effect */
        .menu-item a:hover {
            background-color: #ddd;
            color: #007bff;
        }

        /* Active State */
        .menu-item.active > a,
        .submenu li.active > a {
            background-color: #007bff;
            color: #fff;
        }

        /* Submenu Styles */
        .submenu {
            list-style: none;
            padding: 0;
            margin: 0;
            position: absolute;
            top: 100%;
            left: 0;
            display: none;
            background-color: #f5f5f5;
            min-width: 150px;
            border: 1px solid #ddd;
        }

        .submenu a {
            padding: 10px;
            display: block;
            color: #333;
        }

        .submenu a:hover {
            background-color: #ddd;
            color: #007bff;
        }

        /* Show Submenu on Hover */
        .menu-item:hover .submenu {
            display: block;
        }
    </style>
</head>
<body>
    <nav>
        <div class="menu">
            <button id="btn1" class="dropdownButton">Home</button>
        <div class="submenu">
        <a href="/AboutUs"> About Us </a>   
            <button class="menu-item has-submenu">
                <button id='btn2' class='subMenubtn'>Services</button>
                <div class="submenu">
                    <button><a href="function.php">Web Design</a></button>
                    <button><a href="contact.php">SEO</a></button>
                    <button><a href="contact.php">Marketing</a></button>
                </div>
            </button>
            <button class="menu-item"><a href="contact.php">About</a></button>
            <button class="menu-item"><a href="function.php">Contact</a></button>
        </div>
    </nav>

    
</body>

What is the difference between _final() and _destroy() method in nodejs (custom writable implementation)

I am currently learning nodejs streams and I came across custom nodejs writable stream implementation.But i am getting trouble understanding what is the difference between _final and _destroy method.

After doing some searches i found that _final method will be called after “Stream.end()”method is called and _destroy method will be called when an error is occured or “stream.destroy()” is called.And all the resource cleanup is done inside _destroy method.But what if i don’t call stream.destroy() or no error is occured in the stream,Will the file resource be not closed?Will it remain opened?

How to correctly generate .d.ts files for library package

I’m working on an JavaScript NPM library package and trying to get typescript to generate a .d.ts file from the jsdocs embedded in the file.

Let’s say I have the following three files:

index.js, the main entry point into library:

export * from "./foo.js";
export * from "./bar.js";

foo.js:

/** This is the foo function */
export function foo()
{
}

and bar.js:

/** This is the bar function */
export function bar()
{
}

I then run tsc with config like so:

{
    "include": [
        "index.js",
    ],
    "compilerOptions": {
        "allowJs": true,
        "declaration": true,
        "emitDeclarationOnly": true,
        "outFile": "index.d.ts",
        "declarationMap": true,
    }
}

and I get an index.ts.d with this:

declare module "foo" {
    /** This is the foo function */
    export function foo(): void;
}
declare module "bar" {
    /** This is the bar function */
    export function bar(): void;
}
declare module "index" {
    export * from "foo";
    export * from "bar";
}
//# sourceMappingURL=index.d.ts.map

But this doesn’t work as expected with the intellisense in VSCode. For example, when adding imports, VS Code adds:

import { foo } from "foo";

instead of

import { foo } from "@myscope/mylib";

So what I’m hoping for is a way for tsc to generate something like this:

declare module "@myscope/mylib" {
    /** This is the foo function */
    export function foo(): void;

    /** This is the bar function */
    export function bar(): void;
}
//# sourceMappingURL=index.d.ts.map

What am I missing? Is there some way to get tsc to generate a .d.ts file where the entire library is considered a single module, with the scoped package name that I want?

Weird response from google maps javascript places API searchByText

I’m using the Maps JavaScript API Text Search (New) searchByText() function to get a list of places in a web app. It’s supposed to return google.maps.places.Place[] according to the @types/google.maps typings, and according to the documentation linked above. But I get a weird object back with intermediate keys Eg, Fg, Hg, Ig, Jg, Kg, Lg, Mg, Ng, Og, Pg, Qg, Rg, Sg, Tg, Ug, Vg with the actual response Place object in the Eg key and some other duplicate crap in some of the other keys (mostly undefined though). What’s going on? The app is Vue and this result was obtained while running it via vite dev server. Haven’t tested any other build.

Code:

  const loader = new Loader({
    apiKey,
    version: '3.58'
  });
  const places: google.maps.PlacesLibrary = await loader.importLibrary('places');
  const request = {
    includedType: 'locality',
    textQuery: 'Bogota',
    fields: ['location', 'formattedAddress', 'types', 'id']
  }
  const result = await places.Place.searchByText(request);
  console.log(result);

Gives (undefined keys omitted):

{
  "places": [
    {
      "id": "ChIJQycDzk1B1moR7LsQHWG_MKs",
      "Eg": {
        "id": "ChIJQycDzk1B1moR7LsQHWG_MKs",
        "location": {...},
        "formattedAddress": "...",
        "types": [
          "doctor",
          "point_of_interest",
          "health",
          "establishment"
        ]
      },
      "Ng": {},
      "Ug": [
        "doctor",
        "point_of_interest",
        "health",
        "establishment"
      ],
      "Fg": {}
    }
  ]
}

TypeScript type error on my servfer action next.js

need help on a server action on my Next.js applicastion, giving me a type error and can’t pinpoint the reason, it appears when there are 3 values on the db.insert for the orderProduct and it always errors out the first value whatever it field it is.

create-order.tsx

products.map(async ({ productId, quantity, variantId }) => {
  await db.insert(orderProduct).values({
    productVariantId: variantId,
    productId: productId,
    quantity,
    orderId: order[0].id,
  })
})

schema

export const orderProduct = pgTable('order_product', {
  id: serial('id').primaryKey(),
  quantity: integer('quantity').notNull(),
  productVariantId: serial('productVariantId')
    .notNull()
    .references(() => productVariants.id, { onDelete: 'cascade' }),
  productId: serial('productId')
    .notNull()
    .references(() => products.id, { onDelete: 'cascade' }),
  orderId: serial('orderId')
    .notNull()
    .references(() => orders.id, { onDelete: 'cascade' }),
})

Types

import * as z from 'zod'

export const createOrderSchema = z.object({
  total: z.number(),
  status: z.string(),
  paymentIntentId: z.string(),
  products: z.array(
    z.object({
      quantity: z.number(),
      productId: z.string(),
      variantId: z.string(),
    }),
  ),
})

Error message

No overload matches this call.
  Overload 2 of 2, '(values: { quantity: number | SQL<unknown> | Placeholder<string, any>; id?: number | SQL<unknown> | Placeholder<string, any> | undefined; productId?: number | SQL<...> | Placeholder<...> | undefined; productVariantId?: number | ... 2 more ... | undefined; orderId?: number | ... 2 more ... | undefined; }[]): PgInsertBase<...>', gave the following error.
    Object literal may only specify known properties, and 'productVariantId' does not exist in type '{ quantity: number | SQL<unknown> | Placeholder<string, any>; id?: number | SQL<unknown> | Placeholder<string, any> | undefined; productId?: number | SQL<...> | Placeholder<...> | undefined; productVariantId?: number | ... 2 more ... | undefined; orderId?: number | ... 2 more ... | undefined; }[]'.ts(2769)

Here’s the error, it will be the same if i move around the values of my db.insert

Data Tables Refresh on Edit / Update

In my project, I have been using Data tables to show the list of data from the database per required view.

So in the view, I have this code

<div class="table-responsive mt-4" style="padding-top:50px;">
    <table id="memberList" class="table table-striped">
        <thead>
            <tr>
                <th>Employee Number</th>
                <th>Employee Name</th>
                <th>Designation</th>
                <th>Department</th>
                <th>Authorization</th>
                <th></th>
            </tr>
        </thead>
    </table>
</div>

the table script

 $('#memberList').DataTable({
     processing: true,
     serverSide: true,
     filter: true,
     scrollY: '400px',
     orderMulti: false,
     ajax: {
         url: getMemberList,
         type: 'POST',
         datatype: 'json'
     },
     columns: [
         { data: "EmpNumber", name: "Employee Number" },
         { data: "EmployeeName", name: "Employee Name" },
         { data: "Dessignation", name: "Designation" },
         { data: "Department", name: "Department" },
         {
             data: "IsAuthorized",
             render: function (data, type, row) {
                 return data
                     ? '<span class="text-success">Allowed</span>'
                     : '<span class="text-danger">Denied</span>';
             },
             name: "Authorization"
         },
         {
             data: "EId",
             render: function (data, type, row) {
                 return `
                 <div class="btn btn-danger delete-member" data-id="${data}">
                     Remove
                 </div>`;
             },
             orderable: false
         }
     ],
     language: {
         search: "Search:"
     }
 });

So in the same view, I have an Add button in which the user selects data from the combo box and clicks the add button then sends that selected value to the controller does the necessary backend process, and saves that on the database table.

Then in the success function, I wanted to refresh the table and I did this

if (response.success) {
  showSuccessToast("Employee added successfully");

  // Refresh the DataTable
  $('#memberList').DataTable().ajax.reload();

  $(ctl).prop("disabled", false).text(originalText);
  closePopup();
}

this did not work and I got an error as
DataTables warning: table id=memberList – Invalid JSON response. For more information about this error, please see http://datatables.net/tn/1

Nav-menu issue in mobile view

So the short story is, I have created a website, and I now seem to be running into an issue with the nav-menu, my nav-menu has a sub menu that drops down to expose some other menus, This works perfectly fine in desktop view, drop-down menus works great but as soon as I go into mobile view the drop-down menu stops working

<nav id="navmenu" class="navmenu">
        <ul>
            <li><a href="index.html#hero" class="active">Home</a></li>
            <li><a href="index.html#about">About</a></li>
            <li><a href="index.html#features">Features</a></li>
            <li class="dropdown"><a href="#"><span>Services</span> <i class="bi bi-chevron-down toggle-dropdown"></i></a>
                <ul>
                    <li><a href="login.html">Client Login (Coming Soon)</a></li>
                    <li><a href="fullwebsite.html">Full Website Design</a></li>
                    <li><a href="singlelandingpage.html">Landing Page Design</a></li>
                    <li><a href="multipagedesign.html">Multi Page Design</a></li>
                    <li><a href="addon.html">Add-On Features</a></li>
                </ul>
            </li>
            <li><a href="blog.html">Blog</a></li>
            <li><a href="index.html#pricing">Pricing</a></li>
            <li><a href="index.html#contact">Contact</a></li>
        </ul>
        <i class="mobile-nav-toggle d-xl-none bi bi-list"></i>
    </nav>

/*--------------------------------------------------------------
# Navigation Menu
--------------------------------------------------------------*/
 
@media (min-width: 1200px) {
  .navmenu .dropdown ul {
    margin: 0;
    padding: 10px 0;
    background: var(--nav-dropdown-background-color);
    display: block;
    position: absolute;
    visibility: hidden;
    top: 100%; /* Align dropdown below parent item */
    left: 0;
    opacity: 0;
    transition: opacity 0.3s ease, top 0.3s ease;
    border-radius: 4px;
    z-index: 99;
    box-shadow: 0px 0px 30px rgba(0, 0, 0, 0.1);
  }
  
    .navmenu ul {
      margin: 0;
      padding: 0;
      display: flex;
      list-style: none;
      align-items: center;
    }
  
    .navmenu li {
      position: relative;
    }
  
    .navmenu a,
    .navmenu a:focus {
      color: var(--nav-color);
      padding: 18px 15px;
      font-size: 16px;
      font-family: var(--nav-font);
      font-weight: 400;
      display: flex;
      align-items: center;
      justify-content: space-between;
      white-space: nowrap;
      transition: 0.3s;
    }
  
    .navmenu a i,
    .navmenu a:focus i {
      font-size: 12px;
      line-height: 0;
      margin-left: 5px;
      transition: 0.3s;
    }
  
    .navmenu li:last-child a {
      padding-right: 0;
    }
  
    .navmenu li:hover>a,
    .navmenu .active,
    .navmenu .active:focus {
      color: var(--nav-hover-color);
    }
  
    .navmenu .dropdown ul {
      margin: 0;
      padding: 10px 0;
      background: var(--nav-dropdown-background-color);
      display: block;
      position: absolute;
      visibility: hidden;
      left: 14px;
      top: 130%;
      opacity: 0;
      transition: 0.3s;
      border-radius: 4px;
      z-index: 99;
      box-shadow: 0px 0px 30px rgba(0, 0, 0, 0.1);
    }
  
    .navmenu .dropdown ul li {
      min-width: 200px;
    }
  
    .navmenu .dropdown ul a {
      padding: 10px 20px;
      font-size: 15px;
      text-transform: none;
      color: var(--nav-dropdown-color);
    }
  
    .navmenu .dropdown ul a i {
      font-size: 12px;
    }
  
    .navmenu .dropdown ul a:hover,
    .navmenu .dropdown ul .active:hover,
    .navmenu .dropdown ul li:hover>a {
      color: var(--nav-dropdown-hover-color);
    }
  
    .navmenu .dropdown:hover > ul {
      visibility: visible;
      opacity: 1;
      top: 100%; /* Prevent overlapping by ensuring dropdown is fully below */
    }
  
    .navmenu .dropdown .dropdown ul {
      top: 0;
      left: 100%; /* Align nested dropdowns to the right */
      visibility: hidden;
      opacity: 0;
    }
    
    .navmenu .dropdown .dropdown:hover > ul {
      visibility: visible;
      opacity: 1;
      top: 0; /* Nested dropdown aligns horizontally */
      left: 100%;
    }
  
    .navmenu .megamenu {
      position: static;
    }
  
    .navmenu .megamenu ul {
      margin: 0;
      padding: 10px;
      background: var(--nav-dropdown-background-color);
      box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.1);
      position: absolute;
      top: 130%;
      left: 0;
      right: 0;
      visibility: hidden;
      opacity: 0;
      display: flex;
      transition: 0.3s;
      border-radius: 4px;
      z-index: 99;
    }
  
    .navmenu .megamenu ul li {
      flex: 1;
    }
  
    .navmenu .megamenu ul li a,
    .navmenu .megamenu ul li:hover>a {
      padding: 10px 20px;
      font-size: 15px;
      color: var(--nav-dropdown-color);
    }
  
    .navmenu .megamenu ul li a:hover,
    .navmenu .megamenu ul li .active,
    .navmenu .megamenu ul li .active:hover {
      color: var(--nav-dropdown-hover-color);
    }
  
    .navmenu .megamenu:hover>ul {
      opacity: 1;
      top: 100%;
      visibility: visible;
    }
  }
  
  /* Mobile Navigation */
  @media (max-width: 1199px) {
    .mobile-nav-toggle {
      color: var(--nav-color);
      font-size: 28px;
      line-height: 0;
      margin-right: 10px;
      cursor: pointer;
      transition: color 0.3s;
    }
  
    .navmenu {
      padding: 0;
      z-index: 9997;
    }
  
    .navmenu ul {
      display: none;
      list-style: none;
      position: absolute;
      inset: 60px 20px 20px 20px;
      padding: 10px 0;
      margin: 0;
      border-radius: 6px;
      background-color: var(--nav-mobile-background-color);
      overflow-y: auto;
      transition: 0.3s;
      z-index: 9998;
      box-shadow: 0px 0px 30px rgba(0, 0, 0, 0.1);
    }
  
    .navmenu a,
    .navmenu a:focus {
      color: var(--nav-dropdown-color);
      padding: 10px 20px;
      font-family: var(--nav-font);
      font-size: 17px;
      font-weight: 500;
      display: flex;
      align-items: center;
      justify-content: space-between;
      white-space: nowrap;
      transition: 0.3s;
    }
  
    .navmenu a i,
    .navmenu a:focus i {
      font-size: 12px;
      line-height: 0;
      margin-left: 5px;
      width: 30px;
      height: 30px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 50%;
      transition: 0.3s;
      background-color: color-mix(in srgb, var(--accent-color), transparent 90%);
    }
  
    .navmenu a i:hover,
    .navmenu a:focus i:hover {
      background-color: var(--accent-color);
      color: var(--contrast-color);
    }
  
    .navmenu a:hover,
    .navmenu .active,
    .navmenu .active:focus {
      color: var(--nav-dropdown-hover-color);
    }
  
    .navmenu .active i,
    .navmenu .active:focus i {
      background-color: var(--accent-color);
      color: var(--contrast-color);
      transform: rotate(180deg);
    }
  
    .navmenu .dropdown ul {
      margin: 0;
      padding: 10px 0;
      background: var(--nav-dropdown-background-color);
      display: block;
      position: absolute;
      visibility: hidden;
      top: 130%;
      left: 0;  /* Set left to 0 for better alignment */
      opacity: 0;
      transition: 0.3s;
      border-radius: 4px;
      z-index: 99;
      box-shadow: 0px 0px 30px rgba(0, 0, 0, 0.1);
    }

    
  
    .navmenu .dropdown ul ul {
      background-color: rgba(33, 37, 41, 0.1);
    }
  
    .navmenu .dropdown>.dropdown-active {
      display: block;
      background-color: rgba(33, 37, 41, 0.03);
    }
  
    .mobile-nav-active {
      overflow: hidden;
    }
  
    .mobile-nav-active .mobile-nav-toggle {
      color: #fff;
      position: absolute;
      font-size: 32px;
      top: 15px;
      right: 15px;
      margin-right: 0;
      z-index: 9999;
    }
  
    .mobile-nav-active .navmenu {
      position: fixed;
      overflow: hidden;
      inset: 0;
      background: rgba(33, 37, 41, 0.8);
      transition: 0.3s;
    }
  
    .mobile-nav-active .navmenu>ul {
      display: block;
    }
  }

(function() {
  "use strict";

  /**
   * Apply .scrolled class to the body as the page is scrolled down
   */
  function toggleScrolled() {
    const selectBody = document.querySelector('body');
    const selectHeader = document.querySelector('#header');
    if (!selectHeader.classList.contains('scroll-up-sticky') && !selectHeader.classList.contains('sticky-top') && !selectHeader.classList.contains('fixed-top')) return;
    window.scrollY > 100 ? selectBody.classList.add('scrolled') : selectBody.classList.remove('scrolled');
  }

  document.addEventListener('scroll', toggleScrolled);
  window.addEventListener('load', toggleScrolled);

  /**
   * Mobile nav toggle
   */
  const mobileNavToggleBtn = document.querySelector('.mobile-nav-toggle');

  function mobileNavToogle() {
    document.querySelector('body').classList.toggle('mobile-nav-active');
    mobileNavToggleBtn.classList.toggle('bi-list');
    mobileNavToggleBtn.classList.toggle('bi-x');
  }
  mobileNavToggleBtn.addEventListener('click', mobileNavToogle);

  /**
   * Hide mobile nav on same-page/hash links
   */
  document.querySelectorAll('#navmenu a').forEach(navmenu => {
    navmenu.addEventListener('click', () => {
      if (document.querySelector('.mobile-nav-active')) {
        mobileNavToogle();
      }
    });

  });

  /**
   * Toggle mobile nav dropdowns
   */
  document.querySelectorAll('.navmenu .toggle-dropdown').forEach(navmenu => {
    navmenu.addEventListener('click', function(e) {
      e.preventDefault();
      this.parentNode.classList.toggle('active');
      this.parentNode.nextElementSibling.classList.toggle('dropdown-active');
      e.stopImmediatePropagation();
    });
  });

  /**
   * Preloader
   */
  const preloader = document.querySelector('#preloader');
  if (preloader) {
    window.addEventListener('load', () => {
      preloader.remove();
    });
  }

  /**
   * Scroll top button
   */
  let scrollTop = document.querySelector('.scroll-top');

  function toggleScrollTop() {
    if (scrollTop) {
      window.scrollY > 100 ? scrollTop.classList.add('active') : scrollTop.classList.remove('active');
    }
  }
  scrollTop.addEventListener('click', (e) => {
    e.preventDefault();
    window.scrollTo({
      top: 0,
      behavior: 'smooth'
    });
  });

  window.addEventListener('load', toggleScrollTop);
  document.addEventListener('scroll', toggleScrollTop);

  /**
   * Animation on scroll function and init
   */
  function aosInit() {
    AOS.init({
      duration: 600,
      easing: 'ease-in-out',
      once: true,
      mirror: false
    });
  }
  window.addEventListener('load', aosInit);

  /**
   * Initiate glightbox
   */
  const glightbox = GLightbox({
    selector: '.glightbox'
  });

  /**
   * Frequently Asked Questions Toggle
   */
  document.querySelectorAll('.faq-item h3, .faq-item .faq-toggle').forEach((faqItem) => {
    faqItem.addEventListener('click', () => {
      faqItem.parentNode.classList.toggle('faq-active');
    });
  });

  /**
   * Init swiper sliders
   */
  function initSwiper() {
    document.querySelectorAll(".init-swiper").forEach(function(swiperElement) {
      let config = JSON.parse(
        swiperElement.querySelector(".swiper-config").innerHTML.trim()
      );

      if (swiperElement.classList.contains("swiper-tab")) {
        initSwiperWithCustomPagination(swiperElement, config);
      } else {
        new Swiper(swiperElement, config);
      }
    });
  }

  window.addEventListener("load", initSwiper);

  /**
   * Correct scrolling position upon page load for URLs containing hash links.
   */
  window.addEventListener('load', function(e) {
    if (window.location.hash) {
      if (document.querySelector(window.location.hash)) {
        setTimeout(() => {
          let section = document.querySelector(window.location.hash);
          let scrollMarginTop = getComputedStyle(section).scrollMarginTop;
          window.scrollTo({
            top: section.offsetTop - parseInt(scrollMarginTop),
            behavior: 'smooth'
          });
        }, 100);
      }
    }
  });

  /**
   * Navmenu Scrollspy
   */
  let navmenulinks = document.querySelectorAll('.navmenu a');

  function openModal(title, description) {
    document.getElementById('modalTitle').innerText = title;
    document.getElementById('modalDescription').innerText = description;
    document.getElementById('designModal').style.display = 'block';
  }
  
  function closeModal() {
    document.getElementById('designModal').style.display = 'none';
  }
  
  // Close the modal when clicking outside of it
  window.onclick = function(event) {
    if (event.target == document.getElementById('designModal')) {
      closeModal();
    }
  }
  
  function navmenuScrollspy() {
    navmenulinks.forEach(navmenulink => {
      if (!navmenulink.hash) return;
      let section = document.querySelector(navmenulink.hash);
      if (!section) return;
      let position = window.scrollY + 200;
      if (position >= section.offsetTop && position <= (section.offsetTop + section.offsetHeight)) {
        document.querySelectorAll('.navmenu a.active').forEach(link => link.classList.remove('active'));
        navmenulink.classList.add('active');
      } else {
        navmenulink.classList.remove('active');
      }
    })
  }
  window.addEventListener('load', navmenuScrollspy);
  document.addEventListener('scroll', navmenuScrollspy);

})();

[So in my css code i have this section. In that section i have two lines, Visibility and opacity,

Original:
Visibility: hidden
Opacity: 0

New Code:
Visibility: visible
Opacity: 1

Changing only those two lines actually make the box appear but looks weird](https://i.sstatic.net/nCMKW8PN.png)

Jest Test Fails with “Cannot Find Module ‘mock-pdf.worker.js'” When Mocking pdf.worker.js for pdfjs-dist

I’m trying to write Jest tests for a project that uses pdfjs-dist to parse PDF files. I need to mock the worker file (pdf.worker.js) used by pdfjs-dist to avoid loading the real worker during tests. However, I keep running into this error:

Setting up fake worker failed: "Cannot find module 'mock-pdf.worker.js' from 'node_modules/pdfjs-dist/legacy/build/pdf.js'".

What I’ve Tried:
Mocking the Worker File: I created a mock file at mocks/pdfjs-dist/legacy/build/pdf.worker.js with the following contents:

console.log("Mock pdf.worker.js loaded");
module.exports = {}; // Simulates an empty worker

Setting Module Name Mapper: In my jest.config.js file, I added the following to map the worker file:

module.exports = {
  moduleNameMapper: {
    "^pdfjs-dist/legacy/build/pdf.worker.js$": "<rootDir>/__mocks__/pdfjs-dist/legacy/build/pdf.worker.js",
  },
};

Setting Worker in Tests: In my test file (tests/parse-resume-from-pdf.test.js), I added:

beforeEach(() => {
  const pdfjs = require("pdfjs-dist/legacy/build/pdf");
  pdfjs.GlobalWorkerOptions.workerSrc = require.resolve(
    "__mocks__/pdfjs-dist/legacy/build/pdf.worker.js"
  );
});

Test Code: Here’s the relevant part of my test:

const { parseResumeFromPdf } = require("../src/parse-resume-from-pdf");
const path = require("path");

describe("Resume Parser - Parsing PDFs", () => {
  it("should parse a sample resume", async () => {
    const filePath = path.resolve(__dirname, "../Waleed-Khali-Software_Engineer_Resume.pdf");
    let parsedResume;
    try {
      parsedResume = await parseResumeFromPdf(filePath);
    } catch (error) {
      console.error("Error parsing resume:", error);
      throw error; // Fail the test if parsing fails
    }

    expect(parsedResume).toHaveProperty("profile");
    expect(parsedResume.profile).toHaveProperty("name");
    expect(parsedResume.profile.name).toBeTruthy();
  });
});

I see the log message Mock pdf.worker.js loaded, so I know the mock is being loaded.

If I use console.log(require.resolve(“pdfjs-dist/legacy/build/pdf.worker.js”)), it correctly resolves to my mock

My Questions:
Why does pdfjs-dist fail to find my mocked worker even though Jest resolves it correctly with moduleNameMapper?
Is there something I’m missing in the Jest configuration or the way I’m mocking the worker file?
How can I properly mock pdf.worker.js so that pdfjs-dist works in my tests?

+5 every 10 seconds [closed]

I’m new to coding and am trying to create a basic clicker game but can’t get upgrades to work I’m trying to add 5 to a variable every 10 seconds but you also need to check if they have enough to buy the item and then increase the price by 25%

this is my code so far

var clicks = 0;

function onClick() {
  clicks += 1;
  document.getElementById("clicks").innerHTML = clicks;
};

function upgrade1() {
  clicks += 1;
}

Submitting HTML form using JavaScript [duplicate]

I have a simple HTML form for which I use Javascript to submit the form. But when I run the code the result is a 404 error or I don’t go to link address. I am aiming to submit to https://google.com?type=type in this example.

JS Fiddle code here

var url = 'https://google.com'
var query = document.querySelector('form').getAttribute('action');
document.querySelector('form').addEventListener('submit', function(event) {
  event.preventDefault();
  fetch(`${url}/${query}`, {
    method: 'POST',
    body: new URLSearchParams(new FormData(event.target))
  }).then(this.reset.bind(this));
});
<form action="?type=type">
  <input type="email" name="SENDER" placeholder="Your email" required="required" />
  <input type="text" name="name" placeholder="Your name" required="required" />
  <textarea name="message" cols="30" rows="5" required="required"></textarea>
  <input type="submit" value="Submit" />
</form>

Cookies are not being sent from server side

Server side:

    const app = express();
    app.use(cookieParser());
    app.use(express.json());
    app.use(cors({ origin: "http://localhost:5173", methods: ["GET", "POST"], credentials: true }));
    
    export const test = (req, res) => {
      return res
        .cookie("Test", "TESTCOOKIE", { maxAge: 100000000, secure: true, sameSite: "none" })
        .status(200)
        .json("cookies sent");
    };
    
    const router = express.Router();
    router.get("/test", test);

Client side:

  axios.get("http://localhost:9999/api/test");

The problem: There is no cookie in the browser. I am not getting any cookie

What I want: I want to receive cookie from the server and store them in a user’s browser

What’ve I tried:

  1. I used Insomnia (an app for server requests) and it is working, I
    could get the test cookie.
  2. I opened the “http://localhost:9999/api/test” in my browser and it worked as well.

TextInput blinking / flinking when i format text in onChangeText React Native

I’m trying a simple example of dynamic input formatting (if input = 3 => save text, else – text old):

const [text, setText] = useState('');

return(
    <View>
        <TextInput
            value={text}
            onChangeText={innerText => {
                if (innerText === '3')
                    setText(innerText);
                }}
        />
    </View>)

What happens:
I enter anything, try to correct the input – I get the input blinking for a few seconds – the value that I enter from the keyboard appears for a moment, then returns to the previous state, thanks to the “filter” in onChangeText (for example, you can enter only the number 3, and when entering the rest – I actually see all the characters that I enter for some time, and only then they are erased in accordance with the value).
How to avoid this?

I enter anything, try to correct the input – I get the input blinking for a few seconds – the value that I enter from the keyboard appears for a moment, then returns to the previous state, thanks to the “filter” in onChangeText (for example, you can enter only the number 3, and when entering the rest – I actually see all the characters that I enter for some time, and only then they are erased in accordance with the value).

How to avoid this? I tried a bunch of ways:

  • changing onChangeText to onChange
  • changing onChangeText to onKeyPress
    and all their combinations
  • two states connected via useEffect (the first was set in value, the second was set in onChangeText, and in useEffect I equated them)
  • defaultValue does not suit my tasks
  • maxLength does not suit my tasks, as well as editable = false
  • MaskInput has the same problem when the mask ends and you try to enter something longer than its length
    react-native-text-input-mask and react-native-advanced-input-mask work well for me, because they are direct wrappers over native inputs (a wrapper over a native input would be perfect for me), but in the first one my customNotations crash on Android, and in the second one if I open <Modal>, then my value disappears, as if the value is empty, although I made a <Text> component next to it that duplicates the value, and the value itself is fine, it is simply reset inside the component, and if I use defaultValue, then onChangeText will be called twice, which greatly breaks the processing logic
    I’m desperate, what should I do with this, please tell me! I need something that will help process and replace user input BEFORE it is displayed

javascript show kb left of a download

is it possible to show the user via javascript how much is left (in kb) to fully download a gif file from a remote server?

    function downgif(id, img){
    //show downloading
    Show('downloadgif');
    
    //chenge img
    document.getElementById(id).src=img;
   
   //test if complete
    var completeInterval = null, renderedInterval = null, count = 0;
    var theImg = document.getElementById(id);
    theImg.src = img;
    // Wait for image to be loaded (but not necessarily rendered)
    completeInterval = setInterval(function() {
      if (theImg.complete) {
        // Cancel checking once IMG is loaded OR we've tried for ~9s already
        clearInterval(completeInterval);
        completeInterval = null;
          // IMG is now 'complete' - but that just means it's in the render queue...
          // Wait for naturalWidth and naturalHeight to be > 0 since this shows
          // that the image is done being RENDERED (not just 'loaded/complete')
          renderedInterval = setInterval(function() {
            if (theImg.naturalHeight > 0 && theImg.naturalWidth > 0) {
              clearInterval(renderedInterval);
              renderedInterval = null;

              //hide downliading
              Hide('downloadgif');
            }
          }, 100);
      }
    }, 450);
 
}

Duplicated and unrelated titles appear when searching for specific show using search field

I’m using the Jikan API to create an anime gallery of some sort, one of the features I wanted to include was to be able to search for a specific anime title within the gallery. My issue is that with my current search input field; despite specifying a show, it will show the specific title you searched for along with a couple of duplicated titles of an entirely different show.

Another issue I’m having is that despite setting a limit to how many shows data will be fetched, once I clear the search field, those same duplicates will be added onto the gallery despite the limitation.

Image of gallery when user inputs a specific anime title

App.js

import './App.css';
import AnimeGallery from './components/AnimeGallery';
import Footer from './components/Footer';
import Header from './components/Header';
import NavFilter from './components/NavFilter';
import { useState, useEffect } from 'react';

function App() {
  const animeApi = 'https://api.jikan.moe/v4/top/anime?type=tv&sfw=true&limit=12&filter=airing';

  const [animeList, setAnimeList] = useState([]);
  const [filteredAnime, setFilteredAnime] = useState([])

  useEffect(() => {
    const fetchAnimeGenre = async () => {
      const result = await fetch(animeApi);
      const data = await result.json();
      setAnimeList(data.data);
      setFilteredAnime(data.data);
    };
    fetchAnimeGenre();
  }, []);


  return (
    <>
      <Header />
      <NavFilter animeList={animeList} setFilteredAnime={setFilteredAnime} />
      <AnimeGallery animeList={filteredAnime} />
      <Footer />
    </>
  );
}

export default App;

NavFilter.js

import '../styles/NavFilter.module.css'
import { useState } from 'react';

const NavFilter = ({ animeList, setFilteredAnime }) => {

    const [searchAnime, setSearchAnime] = useState('');

    const preventReload = (e) => {
        e.preventDefault();
    }

    const handleSearchNav = (e) => {
        const searchTitle = e.target.value;
        setSearchAnime(searchTitle);

        if (searchTitle === '') {
            setFilteredAnime(animeList);
        } else {

            const filteredResults = animeList.filter(anime =>
                anime.title.toLowerCase().includes(searchTitle.toLowerCase())
            );

            setFilteredAnime(filteredResults);
        };
    }



    return (
        <>
            <nav>
                <div className="w-full p-5 shadow-xl">
                    <ul className="flex justify-center tracking-wider text-sm">

                        <li>
                            <form
                                onSubmit={preventReload}
                            >
                                <input
                                    type="text"
                                    className="rounded-md px-8 py-1"
                                    placeholder="Search Anime..."
                                    value={searchAnime}
                                    onChange={handleSearchNav}></input>
                            </form>
                        </li>
                    </ul>
                </div>
            </nav>
        </>
    )
}

export default NavFilter;

AnimeGallery.js

import '../styles/AnimeGallery.module.css';

const AnimeGallery = ({ animeList }) => {

    return (
        <>
            <section className="anime-gallery container mx-auto grid sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 px-3 py-3 mt-20">
                {animeList.map((anime, index) => (
                    <article className="anime-card flex mx-3 my-2 rounded-lg h-72 bg-gray-dark shadow-md hover:-translate-y-3" key={anime.mal_id}>
                        <img className="anime-card-poster h-72" src={anime.images.jpg.image_url} alt={anime.title} />
                        <div className="anime-details p-3 w-full flex flex-col overflow-ellipsis overflow-auto">
                            <h3 className="anime-card-title text-xl tracking-wide text-balance text-baby-blue font-bold"> {anime.title}</h3>
                            <p className="anime-card-synopsis text-sm mt-2 text-gray-light"> Episodes: {anime.episodes || 'N/A'}</p>
                            <p className="anime-card-rating text-sm text-gray-light"> Rating: {anime.score}</p>
                            <p className="anime-card-status text-sm text-gray-light"> Status: {anime.status}</p>
                            <p className="anime-genres text-sm text-gray-light flex flex-wrap">
                                {anime.genres.map((genre) => (
                                    <p key={genre.mal_id} className="genre-btn px-2 bg-seafoam ms-1 rounded-lg mb-1 mt-2">{genre.name}</p>
                                ))}
                            </p>
                        </div>
                    </article>
                ))}
            </section>
        </>
    )
}

export default AnimeGallery;

Link to repo

For the duplicated titles I did try setting a key to equal the specific id of the show from the API but the duplicates are still present, and I’d also tried using a reduce method in place of my filter.

I also tried utilizing derived state and kept my state variable animeList as the only and entire list of the anime then one other state just for my search query so I could set the filter and specifications within my render, I didn’t notice any changes with that approach either, but to be fair, I had to do a lot of research on the concept of derived state so perhaps I didn’t implement it well.

TypeScript cannot find module only in production environment

I have a monorepo that houses an Express project, located at apps/api.

Running my build command in my local environment works perfectly fine. However, when deploying on DigitalOcean, I suddenly get the following output:

app/account/brands/BrandService.ts(8,43): error TS2307: Cannot find module '../../../core/service' or its corresponding type declarations.
app/account/brands/BrandService.ts(29,25): error TS2339: Property 'getIdBase' does not exist on type 'BrandService'.
app/account/brands/BrandService.ts(78,33): error TS2554: Expected 0 arguments, but got 2.

These errors are repeated hundreds of times across many files in my project.

The file I am importing definitely exists, so I am not sure why TypeScript suddenly struggles to find them in deployment.

This is apps/api/package.json:

{
    "name": "api",
    "main": "./.dist/app/index.js",
    "type": "module",
    "engines": {
        "node": "18.x"
    },
    "scripts": {
        "build": "tsc && tsc-alias",
        "start": "node .dist/app/index.js"
    },
    "dependencies": {
        "bcrypt": "^5.1.1",
        "cors": "^2.8.5",
        "dotenv": "^16.4.5",
        "express": "^4.18.2",
    },
    "devDependencies": {
        "@tsconfig/node18": "^18.2.4",
        "@types/express": "^4.17.21",
        "@types/node": "^20.14.2",
        "tsc-alias": "^1.8.10",
        "tsx": "^4.16.5",
        "typescript": "^5.6.2",
    }
}

This is apps/api/tsconfig.json:

{
    "compilerOptions": {
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        
        "esModuleInterop": true,
        "skipLibCheck": true,
        "resolveJsonModule": true,  
        "isolatedModules": true, 
        "allowJs": false,
        "lib": ["ES2020"], 
        "target": "ES2020",   
        "module": "ESNext",   
        "moduleResolution": "node",
        "moduleDetection": "force",    

        "rootDir": ".",
        "baseUrl": ".",
        "outDir": "./.dist/",
        "sourceMap": true
    },

    "exclude": [
        "node_modules",
        ".dist"
    ]
}

Finally, apps/api/core/service/index.ts:

export * from "./CoreService";