using useEffect keep on calling api

I am trying to call rest api using useEffect but it’s keeping on call rest spi unlimited time.

‘user’ is from createContext.

Below is the code snippet

  useEffect(() => {
    const fetchData = async () => {
      try {
        const recievedUser = await Apis.getUser(user);
        setProfile(recievedUser.data);
        if (recievedUser.data) {
          // console.log(imageUrl)
          fetchImage();
        }
      } catch (error) {
        console.log(error.response);
      }
    };

    const fetchImage = async () => {
      try {
        const response = await Apis.getUserImage(user);
        setImageUrl(URL.createObjectURL(response.data));
      } catch (error) {
        console.log(error);
      }
    };

    fetchData();
  }, [user, imageUrl]);

How to Open a React Modal on an Active Page from a Chrome Extension Side Panel?

I am developing a Chrome Extension with a side panel, and I need to open a React modal on the active webpage when a button inside the side panel is clicked. However, since the extension runs in a separate DOM (inside the side panel), the modal does not appear on the main webpage.

What I Have Tried:

Using Portals – Portals only work within the same React app, but since the extension runs in a different DOM, this does not work.

Content Script Injection – I used chrome.runtime.sendMessage from my extension to send a message to a content.js script, which then injects a simple modal () into the page.

React Component Injection – I tried injecting a React.createElement-based component into the page but struggled with rendering my React modal dynamically.

My Setup:

Manifest.json (Permissions & Configuration for the Side Panel)

Background.js (Handles extension events and sends messages to content scripts)

Content.js (Injects the modal when a message is received)

React Component (RewriteModal.tsx) – This is the modal I want to show on the active webpage.

Code

manifest.json

  "manifest_version": 3,
  "name": "ABC",
  "version": "1.0.0",
  "description": "ABC",
  "action": {
    "default_popup": "index.html",
    "default_title": "ABC"
  },
  "side_panel": {
    "default_path": "index.html",
    "open_at_install": true
  },
  "permissions": ["tabs", "scripting", "activeTab"],
  "host_permissions": ["*://*/*"],
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["http://*/*", "https://*/*"],
      "js": ["content.js"],
      "run_at": "document_end"
    }
  ]
}

background.js

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === "SHOW_MODAL") {
    chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
      if (tabs[0]) {
        chrome.tabs.sendMessage(tabs[0].id, { type: "INJECT_MODAL" });
      }
    });
  }
});

content.js

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === "INJECT_MODAL") {
    console.log("Injecting modal...");

    if (document.getElementById("extension-modal")) return;

    const modal = document.createElement("div");
    modal.id = "extension-modal";
    modal.style.position = "fixed";
    
    modal.style.zIndex = "9999";

    modal.innerHTML = `
      <div style="background: white; padding: 20px; border-radius: 10px; text-align: center;">
        <h2>Modal</h2>
        <p>This modal is injected </p>
        <button id="close-modal-button">Close</button>
      </div>
    `;

    document.body.appendChild(modal);

    document.getElementById("close-modal-button").addEventListener("click", () => {
      modal.remove();
    });
  }
});

React Modal

import React, { useEffect, useState } from "react";

interface odalProps {
  isOpen?: boolean;
  onClose?: () => void;
}

export default function Modal({ isOpen = false, onClose = () => {} }: ModalProps) {
  const [isVisible, setIsVisible] = useState(false);

  useEffect(() => {
    if (isOpen) {
      setIsVisible(true);
      document.body.style.overflow = "hidden";
    } else {
      const timer = setTimeout(() => setIsVisible(false), 200);
      document.body.style.overflow = "unset";
      return () => clearTimeout(timer);
    }
  }, [isOpen]);

  if (!isVisible) return null;

  return (
    <div
      style={{
        display: isOpen ? "block" : "none",
        position: "fixed",
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        background: "rgba(0, 0, 0, 0.5)",
        zIndex: 1000,
      }}
    >
      <div
        style={{
          maxWidth: "600px",
          margin: "100px auto",
          padding: "20px",
          background: "white",
          borderRadius: "10px",
        }}
      >
        <h2>Injected Modal</h2>
        <button onClick={onClose} style={{ padding: "10px", borderRadius: "5px" }}>
          Close
        </button>
      </div>
    </div>
  );
}

The Issue:

  • The modal in content.js injects correctly, but I want to render my
    React component (RewriteModal.tsx) instead of manually creating a .
  • Since the React app runs inside the extension side panel, I
    can’t directly use ReactDOM.render().
  • I tried
    chrome.scripting.executeScript() to inject React into the page, but
    I couldn’t get my modal component to render properly.

What I Need Help With:

  • How can I inject my React modal into the active webpage dynamically?

  • Is there a way to share my React app’s components between the side panel and the active page?

  • How can I properly inject my React modal while ensuring it remains interactive?

Apparent dynamic imports from ajv/dist/runtime in vendor.js build from Angular 18 using latest 8.17.1

I am using latest version of AJV Ajv JSON schema validator in an Angular 18 project. I have a single file that imports the AJV libary, sets up its options and uses it to validate my app’s JSON. I can provide more implementation details if needed.

I’m not specifically referencing any ajv/dist/runtime modules but when I build my project, I’m seeing 4 different references that appear to be strings referencing dynamic includes in the vendor.js file.

This is preventing my exported web component from running in Salesforce.com as a LWC due to the apparent use of dynamic imports:

Here are the references from vendor.js:

code: e._'require("ajv/dist/runtime/validation_error").default' }));
e.code = 'require("ajv/dist/runtime/equal").default',
s.code = 'require("ajv/dist/runtime/ucs2length").default'
e.code = 'require("ajv/dist/runtime/uri").default',

Does anyone know if there is a flag I can pass in the options to prevent this or perhaps another workaround? I’ve tried several mitigation approaches/methods in the angular.json to no avail.

unable to retrive the data dynamically by filtering from database using servlets and mysql

I created a Dynamic Java Project with eclipse using sevlets mysql and trying to retrive the data dynamically when selected the particular discipline or batch. everything working fine and also the json response, etc but noting is displayed when executed. this is my servletPortfolioServlet.java

 @WebServlet("/portfolios")
    public class PortfolioServlet extends HttpServlet {
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            response.setContentType("application/json");
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setCharacterEncoding("UTF-8");
            PrintWriter out = response.getWriter();
            JSONArray portfolioList = new JSONArray();
            Connection conn = null;
            Statement stmt = null;
            ResultSet rs = null;
            try {
                // Database Connection
                Class.forName("com.mysql.cj.jdbc.Driver");
                conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/xxxx?useSSL=false", "root","xxxx");
                stmt = conn.createStatement();
                rs = stmt.executeQuery("SELECT * FROM users");
    
                // Convert ResultSet to JSON
                while (rs.next()) {
                    JSONObject portfolio = new JSONObject();
                    portfolio.put("id", rs.getInt("id"));
                    portfolio.put("full_name", rs.getString("full_name"));
                    portfolio.put("discipline", rs.getString("discipline"));
                    portfolio.put("batch", rs.getString("batch"));
                    portfolio.put("keywords", rs.getString("keywords"));
                    portfolio.put("profile_photo", "image?type=profile_photo&id=" + rs.getInt("id")); 
                    portfolio.put("background_image", "image?type=background_image&id=" + rs.getInt("id"));
                    portfolioList.put(portfolio);
                }
                out.print(portfolioList.toString());
                out.flush();
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                JSONObject errorResponse = new JSONObject();
                errorResponse.put("error", "Failed to load portfolios: " + e.getMessage());
                out.print(errorResponse.toString());
                out.flush();
    
            } finally {
                try {
                    if (rs != null)
                        rs.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    if (stmt != null)
                        stmt.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    if (conn != null)
                        conn.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

ImageServlet.java:

@WebServlet("/image")
public class ImageServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String type = request.getParameter("type"); // "portfolio", or "background"
        int id = Integer.parseInt(request.getParameter("id"));

        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/xxxx?useSSL=false", "root","xxxx");
            PreparedStatement stmt = conn.prepareStatement("SELECT " + type + " FROM users WHERE id = ?");
            stmt.setInt(1, id);
            ResultSet rs = stmt.executeQuery();

            if (rs.next()) {
                byte[] imgData = rs.getBytes(1);
                String contentType = "image/jpeg"; // Default
                if (imgData.length > 4 && imgData[0] == (byte) 0x89 && imgData[1] == (byte) 0x50) {
                    contentType = "image/png"; // PNG signature detected
                }
                response.setContentType(contentType);
                OutputStream os = response.getOutputStream();
                os.write(imgData);
                os.close();
            }
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

index.html:

<!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" />
      <link rel="stylesheet" href="assets/css/style.css" />
      <title></title>
    </head>
    <body>
      <section class="header">
        <div class="hero__container">
          <div class="logo__container">
            <img src="assets/images/logo.png" alt="Logo" />
          </div>
          <div class="hero__content">
            <p>Discover diverse portfolios from <br />the xxxxx</p>
            <div class="connect__data">
              <div class="hero__title-1"><span>connect</span><div class="circle"></div></div>
              <div class="hero__title-2"><span>collaborate</span><div class="circle"></div></div>
              <div class="hero__title-3"><span>create</span><div class="circle"></div><div class="circle-cut"></div></div>
            </div>
          </div>
        </div>
      </section>
    
      <!-- Filters Container -->
      <section class="body__container">
        <div class="filter__container">
          <div class="filter_buttons">
            <button class="filter-btn active" data-name="All">All Programs</button>
            <button class="filter-btn" data-name="IndustrialDesign">Industrial Design</button>
            <button class="filter-btn" data-name="CommunicationDesign">Communication Design</button>
            <button class="filter-btn" data-name="TextileandApparelDesign">Textile and Apparel Design</button>
          </div>
    
          <!-- Dropdown Menu -->
          <div class="dropdown">
            <div class="select">
              <div class="selected placeholder">All batches</div>
              <i class="bi bi-chevron-down caret"></i>
            </div>
          </div>
        </div>
    
        <!-- Dynamic Card Container -->
        <div class="card-container">
          <!-- Cards will be loaded dynamically here -->
        </div>
      </section>
    
      <script src="assets/js/index.js"></script>
    </body>
    </html>

JavaScript:

document.addEventListener(“DOMContentLoaded”, function() {
console.log(“Script loaded, waiting for portfolios…”);

    const cardContainer = document.querySelector(".card-container");
    if (!cardContainer) {
        console.error("Error: .card-container not found!");
        return;
    }

    const loadingMessage = document.createElement("p");
    loadingMessage.className = "loading-message";
    loadingMessage.innerText = "Loading portfolios...";
    cardContainer.appendChild(loadingMessage);

    console.log("Fetching data from /portfolios...");

    fetch("/Student/portfolios")
        .then(response => {
            console.log("Response received:", response);

            if (!response.ok) {
                throw new Error(`HTTP error! Status: ${response.status}`);
            }

            return response.json();
        })
        .then(data => {
            console.log("Fetched data:", data);

            cardContainer.innerHTML = ""; // Clear loading message

            if (!Array.isArray(data) || data.length === 0) {
                console.warn("No portfolios found:", data);
                cardContainer.innerHTML = "<p>No portfolios found.</p>";
                return;
            }

            data.forEach(portfolio => {
                console.log("Processing portfolio:", portfolio);

                const profilePhotoURL = "/Student" + portfolio.profile_photo;
                const backgroundImageURL = "/Student" + portfolio.background_image;

                console.log("Updated Profile Photo URL:", profilePhotoURL);
                console.log("Updated Background Image URL:", backgroundImageURL);

                const cardHTML = `
                <div class="card" data-name="${portfolio.discipline}" data-batch="${portfolio.batch}">
                    <img class="card__image" src="${portfolio.background_image}" alt="Portfolio Image" />
                    <div class="card__overlay">
                        <div class="card__header">
                            <img src="${portfolio.profile_photo}" class="card__thumb" alt="Profile Image" />
                            <div class="card__header-text">
                                <h3 class="card__title">${portfolio.full_name}</h3>
                                <p class="card__status">${portfolio.discipline}, ${portfolio.batch}</p>
                            </div>
                        </div>
                        <div class="card__descraption-box">
                            <h3 class="card__descraption-title">Interests</h3>
                            <p class="card__descraption">${portfolio.keywords}</p>
                        </div>
                    </div>
                </div>`;
                cardContainer.insertAdjacentHTML("beforeend", cardHTML);
            });

            console.log("Portfolios successfully loaded.");
            filterCardsByData();
        })
        .catch(error => {
            console.error("Error loading portfolios:", error);
            cardContainer.innerHTML = `<p>Error loading portfolios. Please try again later.</p>`;
        });
});


// **Filtering Logic**
// Select all filter buttons, filterable cards, and dropdowns
const filterButtons = document.querySelectorAll(".filter_buttons button");
const filterableCards = document.querySelectorAll(".card-container .card");
const dropdowns = document.querySelectorAll(".dropdown");

// Common filtering logic
function filterCardsByData(selectedFilter) {
  filterableCards.forEach((card) => {
    const cardBatch = card.getAttribute("data-batch");
    const cardName = card.dataset.name;

    // Show or hide the card based on filter condition
    if (
      selectedFilter === "All batches" ||
      selectedFilter === "" ||
      cardBatch === selectedFilter ||
      cardName === selectedFilter
    ) {
      // Show card and add reveal animation
      card.classList.remove("hide", "exit");
      setTimeout(() => {
        card.classList.add("reveal"); // Add reveal class for the animation
      }, 10);

      setTimeout(() => {
        card.classList.add("visible"); // Ensure visibility after animation
      }, 500); // Adjust based on reveal animation duration
    } else {
      // Apply exit animation before hiding the card
      card.classList.remove("reveal", "visible");
      card.classList.add("exit");
      setTimeout(() => {
        card.classList.add("hide");
      }, 500); // Ensure card hides after exit animation
    }
  });
}

// Button click event
filterButtons.forEach((button) => {
  button.addEventListener("click", (e) => {
    // Update active button state
    document
      .querySelector(".filter_buttons .active")
      .classList.remove("active");
    e.target.classList.add("active");

    // Get filter value from the button's data-name attribute or default to "All batches"
    const filterValue = e.target.dataset.name || "All batches";

    // Apply the filter
    filterCardsByData(filterValue);
  });
});

// Dropdown logic
dropdowns.forEach((dropdown) => {
  const select = dropdown.querySelector(".select");
  const caret = dropdown.querySelector(".caret");
  const selected = dropdown.querySelector(".selected");
  const menu = document.createElement("ul");

  menu.className = "menu";

  const menuItems = [
    "All batches",
    "Batch of 2017",
    "Batch of 2018",
    "Batch of 2019",
    "Batch of 2020",
    "Batch of 2021",
    "Batch of 2022",
    "Batch of 2023",
    "Batch of 2024",
  ];

  // Add menu items dynamically
  menuItems.forEach((item) => {
    const option = document.createElement("li");
    option.innerText = item;

    // Handle dropdown item selection
    option.addEventListener("click", () => {
      selected.innerText = item;
      caret.classList.remove("caret-rotate");
      menu.classList.remove("menu-open");

      // Add dd-active to the selected option and remove it from others
      menu.querySelectorAll("li").forEach((opt) => {
        opt.classList.remove("dd-active"); // Remove dd-active from all items
      });
      option.classList.add("dd-active"); // Add dd-active to the clicked option

      // Apply the filter
      filterCardsByData(item);
    });

    menu.appendChild(option);
  });

  dropdown.appendChild(menu);

  // Toggle dropdown visibility
  select.addEventListener("click", (event) => {
    event.stopPropagation();
    caret.classList.toggle("caret-rotate");
    menu.classList.toggle("menu-open");
  });

  // Close dropdown if clicked outside
  document.addEventListener("click", (event) => {
    if (!dropdown.contains(event.target)) {
      caret.classList.remove("caret-rotate");
      menu.classList.remove("menu-open");
    }
  });
});

// Ensure cards are visible on page load or refresh by applying the default filter
document.addEventListener("DOMContentLoaded", () => {
  // Trigger the default filter to show all cards (or set to a specific filter if needed)
  filterCardsByData("All batches");
});

CSS:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
/* Font-Falimy  */
@font-face {
  font-family: "manrope-bold";
  src: url(./../fonts/manrope.bold.otf);
}
@font-face {
  font-family: "manrope-extrabold";
  src: url(./../fonts/manrope.extrabold.otf);
}
@font-face {
  font-family: "manrope-light";
  src: url(./../fonts/manrope.light.otf);
}
@font-face {
  font-family: "manrope-medium";
  src: url(./../fonts/manrope.medium.otf);
}
@font-face {
  font-family: "manrope-regular";
  src: url(./../fonts/manrope.regular.otf);
}
:root {
  --baseWhite: #ffffff;
  --accentBlue: #0048ff;
  --textGray: #838383;
  --secoundaryGray: #b3b3b3;
}
body {
  font-family: "manrope-regular" !important;
  font-size: 16px;
  min-height: 100vh;
  background-color: var(--baseWhite);
}
/* .container {
    width: 90%;
    margin: 0 0 0 1em;
} */
.container {
  width: 90%;
  margin: 0 auto;
}
.hero__container {
  width: 98%;
  margin: 10px 0 10px 20px;
}
.logo__container {
  border: 1px solid black;
  width: 253px;
  border-radius: 10px;
  float: right;
  margin: 10px 10px 0 0;
}
.logo__container img {
  width: 250px;
  border-radius: 10px;
}
/* Hero Section */
.hero__container p {
  clear: both;
  font-size: 16px;
  color: var(--textGray);
}
.hero__title-1 {
  width: 100%;
  font-size: 48px;
  font-weight: 300;
  color: black;
  position: relative;
  display: inline-block;
}
.hero__title-1 span {
  font-size: 120px;
  font-family: "manrope-light";
  line-height: 1.1;
}
.hero__title-1::after {
  content: " ";
  height: 7px;
  width: auto;
  background: var(--accentBlue);
  display: block;
  position: absolute;
  top: 80%;
  left: 10.5em;
  right: 0;
}
.hero__title-1 .circle {
  position: absolute;
  width: 77px;
  height: 77px;
  /* opacity: .8; */
  top: 39px;
  left: 64px;
  background: linear-gradient(to bottom, #1c40a5, #728dd1);
  border-radius: 50%;
  margin: 0 5px;
}
.hero__title-2 {
  margin-top: 10px;
  width: 100%;
  font-size: 48px;
  font-weight: 300;
  color: black;
  position: relative;
  display: inline-block;
}
.hero__title-2 span {
  font-size: 120px;
  font-family: "manrope-bold";
  line-height: 1.1;
}
.hero__title-2::after {
  content: " ";
  height: 7px;
  width: auto;
  background: var(--accentBlue);
  display: block;
  position: absolute;
  top: 80%;
  left: 15em;
  right: 0;
}
.hero__title-2 .circle {
  position: absolute;
  /* Position relative to the container */
  width: 77px;
  height: 77px;
  /* opacity: .8; */
  top: 39px;
  left: 69px;
  background: linear-gradient(to bottom, #1c40a5, #728dd1);
  border-radius: 50%;
  margin: 0 5px;
}
.hero__title-3 {
  margin-top: 10px;
  width: 100%;
  font-size: 48px;
  font-weight: 300;
  color: black;
  position: relative;
  display: inline-block;
}
.hero__title-3 span {
  font-size: 120px;
  font-family: "manrope-bold";
  line-height: 1.1;
}
.hero__title-3::after {
  content: " ";
  height: 7px;
  width: auto;
  background: var(--accentBlue);
  display: block;
  position: absolute;
  top: 80%;
  left: 8.9em;
  right: 0;
}
.hero__title-3 .circle {
  position: absolute;
  width: 77px;
  height: 77px;
  /* opacity: .8; */
  top: 39px;
  left: -1px;
  background: linear-gradient(to bottom, #1c40a5, #728dd1);
  border-radius: 50%;
  margin: 0 5px;
}
.circle-cut {
  position: absolute;
  width: 15px;
  height: 77px;
  /* opacity: .8; */
  top: 39px;
  left: 61px;
  background-color: var(--baseWhite);
  margin: 0 5px;
  cursor: not-allowed;
}
/* Body Start */
.body__container {
  width: 95%;
  margin: 0 auto;
  height: auto;
}
/*  */
/* Dropdown Section */
.filter__container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 2em 0;
  border-bottom: 1px solid black;
}
.filter_buttons {
  gap: 30px;
  display: flex;
}
button.filter-btn {
  padding: 20px 0;
  font-family: "manrope-regular";
  font-size: 16px;
  cursor: pointer;
  background-color: var(--baseWhite);
  border: none;
}
.filter-btn.active {
  border-bottom: 2px solid var(--accentBlue);
}

.dropdown {
  display: inline-block;
  position: relative;
}
.label {
  margin-bottom: 3px;
}
/* Select container */
.select {
  cursor: pointer;
  transition: 0.3s;
  background-color: var(--baseWhite);
  border-radius: 5px;
  border: 1px solid black;
  display: flex;
  padding: 5px 15px;
  align-items: center;
  justify-content: space-between;
}
.selected {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.caret {
  margin-left: 10px;
  transition: 0.3s;
}
/* Hover effect for the select container */
.select:hover {
  background-color: var(--secoundaryGray);
}
/* Dropdown Menu Animation */
.menu {
  visibility: hidden;
  border-radius: 5px;
  border: 1px solid black;
  background-color: var(--baseWhite);
  overflow: hidden;
  position: absolute;
  width: 100%;
  top: 146%;
  opacity: 0;
  transform: translateY(-20px);
  transition: visibility 0s, opacity 0.3s ease, transform 0.3s ease;
  z-index: 10;
}
.menu-open {
  visibility: visible;
  opacity: 1;
  transform: translateY(0);
}
/* Caret animation */
.caret {
  margin-left: 10px;
  transition: transform 0.3s ease;
}
.caret-rotate {
  transform: rotate(180deg);
}
/* Menu items */
.menu li {
  cursor: pointer;
  padding: 10px;
}
/* Hover effect for menu items */
.menu li:hover {
  background-color: var(--secoundaryGray);
}
/* Active item style */
.dd-active {
  background-color: var(--accentBlue);
  color: #fff;
}
/* "All batches" - Make clickable */
.menu li:first-child {
  font-weight: normal;
  cursor: pointer;
}
/* Show all batches filter text */
.show-all-batches {
  font-weight: bold;
  color: var(--accentBlue);
  cursor: pointer;
  padding: 10px;
}
/* Card Container */
.card-container {
  margin: 2em 0 5em 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: 50px;
}
.card {
  transform: scale(0) translate(0, 0);
  opacity: 0;
  transition: transform 0.5s ease, opacity 0.5s ease;
  transform-origin: top left;
}
/* When the card becomes visible */
.card.visible {
  transform: scale(1) translate(0, 0);
  opacity: 1;
}
.card {
  background-color: var(--baseWhite);
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  width: 417px;
  height: 312px;
  transition: transform 0.3s ease;
  position: relative;
}
.card.hide {
  display: none;
}
.card__image {
  width: 100%;
  height: 100%;
  max-height: auto;
  object-fit: cover;
}
.card__overlay {
  position: absolute;
  bottom: 0;
  height: 257px;
  left: 0;
  right: 0;
  z-index: 1;
  background-color: rgba(39, 39, 39, 0.6);
  backdrop-filter: blur(5px);
  transform: translateY(100%);
  transition: transform 0.3s ease-in-out, box-shadow 0.4s ease-in-out;
  color: var(--baseWhite);
}
.card:hover .card__overlay {
  transform: translateY(0);
  box-shadow: 0 8px 15px rgba(0, 0, 0, 0);
}
.card__header {
  position: relative;
  display: flex;
  align-items: center;
  gap: 2rem;
  background-color: rgba(33, 33, 33, 0.9);
  padding: 2em;
  transform: translateY(-100%);
  transition: 0.3s ease-in-out;
  font-size: 16px;
  font-family: "manrope-regular";
}
.card:hover .card__header {
  transform: translateY(0);
  background-color: rgba(33, 33, 33, 0);
  transition: 0.3s ease-in-out;
  transition-delay: 0s;
}
.card__thumb {
  flex-shrink: 0;
  width: 3.125em;
  height: 3.125em;
  border-radius: 50%;
}
.card__title {
  font-size: 16px;
  margin: 0 0 0.3rem;
  font-family: "manrope-bold";
}
.card__status {
  font-size: 16px;
}
.card__descraption-box {
  padding: 0 2em 0 7em;
  font-size: 16px;
}
.card__descraption-title {
  margin: 0;
  font-size: 16px;
  font-family: "manrope-bold";
}
.card__descraption {
  font-size: 16px;
  font-family: "manrope-regular";
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
@keyframes revealAnimation {
  0% {
    transform: scale(0) translate(-50%, -50%);
    opacity: 0;
  }
  100% {
    transform: scale(1) translate(0, 0);
    opacity: 1;
  }
}

I want a display as per below screenshot, but i am empty results/data when filtering or when executed:
Output required

But getting below output and displaying message when refreshing the page “loading portfolios…”
enter image description here

So please guide me where is the exact problem why the data is not displaying. I am debugging the code many times but not able to find the actual problem.

Set Custom Icon based on Telemetry Key on Thingsboard

I have send the proper telemetry to my devices, that represents animals, as follows:

enter image description here

When it comes to represent each animal in a Route Map, my goal is to set a specific image based on the value of ‘color’ key on the telemetry. This way, if color value is ‘green’, it will select one icon. If the value is ‘orange’, a second one.

Beacuse I’m new with Thingsboard, I’m not really sure how to achieve this. This is the example that Thingsboard gives:

var type = data['Type'];
if (type == 'thermometer') {
  var res = {
    url: images[0],
    size: 40
  }
  var temperature = data['temperature'];
  if (typeof temperature !== undefined) {
    var percent = (temperature + 60)/120;
    var index = Math.min(3, Math.floor(4 * percent));
    res.url = images[index];
  }
  return res;
}

This example calculates the image url depending on temperature telemetry value for thermometer device type, having 4 different images.

My current approach is the following:

var entityType = dsData[dsIndex]['entityType'];
var entityName = dsData[dsIndex]['name'] || dsData[dsIndex][
    'entityName'
] || "Desconocido"; 

var res = {
    url: images[9], // Imagen predeterminada
    size: 55
};

if (entityType === 'DEVICE') {
    if (entityName.startsWith("Elefant")){
        res.url = images[7];
    }
    else if (entityName.startsWith("Lion")){
        res.url = images[5];
    }
        else if (entityName.startsWith("Rino")){
        res.url = images[2];
    }
}
return res;

In this case, it will set an icon based on the name, which works. However, when I try to do this:

var color = dsData[dsIndex]['color'];

if (color === 'green'){

}

The variable is initialized, but the ‘if’ condition is not met. I have try with ‘green’, “green” and even just green, but nothing works.

Any idea what is going wrong with this?

React 18 App (Integrated via Script) Fails to Navigate React 17 Host Using pushState

I am developing a project using React 18 and React Router DOM 6.28.0, which is embedded into any website via a tag. The project is a tour builder, and I need to navigate the host website programmatically.

To achieve this, I use the following function:

export const navigateTo = (path) => {
  window.history.pushState({}, '', path);
  window.dispatchEvent(new Event('popstate'));
};

This works correctly on most websites. However, there is a specific website that uses React 17 and React Router DOM ^5.3.4, where the URL updates as expected, but the content does not refresh accordingly.

What I’ve Tried:

• Manually dispatching a popstate event to force React Router 5 to detect the change.

• Checking if the host website listens for popstate or has a custom navigation handling mechanism.

• Testing with direct navigation via the browser console (history.pushState(…)).

Questions:

  1. Why does history.pushState work on most websites but not on this one?

  2. How can I force a React Router 5-based website to recognize the navigation change?

  3. Is there an alternative approach to programmatically trigger navigation on the host website while maintaining compatibility with React Router 5?

“e instanceof TouchEvent” in Safari doenst work

On Safari for MacOs this simple code part isnt working for me at all.
e instanceof TouchEvent – it seems that for some reason the “TouchEvent” is not fully supported by Safari for MacOs. It does work on Safari for iOs which is even stranger imo.

ReferenceError: Could not find “TouchEvent” variable.

Is there a proper solution for solving this issue?

Multi-API-CALL-IN-JavaScript

Description

What is the best way to call api if i wanted to call it multiple times. while ensuring api overhit (excessive api call hit per second), which delay technique is best to apply, best way to code it while keeping space and time complexity utilized at minimal as it can be?

*
for intance below is also causes situation where in my mern app i had to call api in multiple times. i.e in loop to fullfill my needs.*

https://shopify.dev/docs/api/admin-rest#rate_limits

CODE to refactor as per description

   if (getEssentials.endpoint === "image") {
      for (let i = 0; i < getEssentials.payload.length; i++) {
        // console.log("aksjdfh", getEssentials.payload[i].media);
        try {
          const options = {
            method: "POST",
            headers: {
              accept: "application/json",
              "content-type": "application/json",
              authorization: "Bearer .......................",
            },
            body: JSON.stringify({
              media: `${getEssentials.payload[i].media}`,
            }),
          };
          // console.log("checkojign", options);
          const response = await fetch(
            `https://gate.whapi.cloud/messages/media/${
              getEssentials.endpoint
            }?caption=${encodeURIComponent(
              getEssentials.payload[i].caption
            )}&to=${to}`,
            options
          );
          const data = await response.json();
          console.log(`Image ${i + 1} sent:`, data);

          await delay();
        } catch (error) {
          console.error(`Error sending image ${i + 1}:`, error);
        }
      }
      return { message: "All images sent successfully" }; // Return a success message after all images are sent
    }

I need to optimize the code. which utilizes minimal resources of backend app. also ensuring api won’t overhit while ensuring all api calls should return the response regardless of thier response status.

How can I remove eval from Criteo’s sslwidget.criteo.com/event which violates Content Security Policy?

I’m developer of the webapp that is using Criteo.
When I open my site, https://sslwidget.criteo.com/event is loaded.
It is a simple javascript code and contains some eval.
I want to remove its eval because it violates Content Security Policy.
I wont use unsafe-eval.
How can I remove eval from https://sslwidget.criteo.com/event?
I think I can remove it by setting something on Criteo’s management screen, But what is the related feature?

For exampel, Google Tag Manager’s eval is related to its custom javascript variable.
What feature is related to Criteo’s sslwidget.criteo.com/event and How can I manage it?
Thank you!

How to create a scalable document element inside a container in HTML

for a program I need to show inside a container a document (not the HTML document element) and this document rect as a fixed width and height and should allow zooming from the user. For me making this is very hard and I need help to create it.

This feature I want to make is the same as how MS Word and Libreoffice Writer scales the document.
Here I’ve reverse engineered how it works:

  1. the document rect begins centered horizontally.
  2. if the document width is less than the screen no need to display horizontal bar.
  3. otherwise if document width is more than screen the horizontal scroolbar show up and allow movement on the X axys.
  4. the scrollbar position is scaled to keep what’s at the center of the screen still at the center and makes the zoom nicer.

I’m using the preact framework to make this app so I’ll show the code of the component.

My first attempt I’ve tried to use CSS only with translate, but the horizontal scrollbar doesn’t show the correct amount to scroll and half the document is not visible.

So I’ve attempted to add javascript for the calculation and I come up with this component:

import { createRef } from "preact";
import { useLayoutEffect, useState } from "preact/hooks";
import type { JSX } from "preact/jsx-runtime";

export interface ContainerScrollScalableProps
{
    width: number,
    height: number,
    scale: number,
    children?: any,
}

export const ContainerScrollScalable = (props: ContainerScrollScalableProps): JSX.Element =>
{
    const container = createRef<HTMLDivElement>();
    const [containerW, setW] = useState<number>(0);
    const [containerH, setH] = useState<number>(0);

    useLayoutEffect(() =>
    {
        if (container.current)
        {
            setW(container.current.clientWidth);
            setH(container.current.clientHeight);
            console.log(container.current.scrollTop);
        }
    }, [container.current]);

    const padTop = containerH * 0.2;
    const padBottom = containerH * 0.4;
    const padXs = 16 * props.scale;

    const scaledW = (props.width * props.scale) + (padXs * 2);
    const sizeW = containerW > scaledW ? containerW : scaledW;

    return (
    <div class="w-100 h-100 overflow-y-scroll overflow-x-auto d-flex" ref={container} >
        <div class="border" style={"transform-origin: top center;"
            + `min-width: ${sizeW.toFixed(0)}px; min-height: ${props.height}px;`} >
            <div style={`width: ${props.width}px; height: ${props.width}px;`
                + "transform-origin: top center;"
                + `transform: translate(${((sizeW / 2) - (props.width / 2) + padXs).toFixed(0)}px, ${(padTop).toFixed(0)}px) scale(${props.scale});`}
                children={props.children} />
        </div>
    </div>
    );
}

Then the component is used like this, will show a border so it doesn’t need actual children elements to test it:

const zoom = getUserZoom(); // range 0.1 --> 3.0

// ...

<ContainerScrollScalable width={1080} height={1920} scale={zoom} />

This component has some problems:

  1. it requires to know the children size as props.
  2. the scale is not perfect because it doesn’t take in account the whole rect of the children.
  3. I want to add some padding to prevent the scaled document to touch the borders of the screen, and still the math is not enough perfect.
  4. the scrollbar positions doesn’t follow the zoom, this is very important.

How could I allow this component to properly scale his content and allow the scrollbar position to follow the scale?

Javascript carousel like-presentation gallery

I’m kind of a beginner developper and at university I have to do a website, and I wanted to do a carousel in the but blackbox AI and ChatGPT didn’t really helped, it didn’t work. My objective is to have a text and an image, then clicking on an arrow, another text and image are shown instead of the one already present
Here’s my containers + the js I tried to use :

        <div class="sectiontext">
            <h2>Voyager à Londres pendant les vacances de Noël</h2>
            <p>Ici, vous allez comprendre à quel point Londres est une destination parfaite pour des vacances à la période de Noël.</p>
            <p>La ville est magnifiquement décorée avec des lumières scintillantes et des marchés de Noël animés.</p>
            <p>Vous pouvez également profiter de la patinoire en plein air et des spectacles de Noël.</p>
            <p>Ne manquez pas de visiter les célèbres attractions touristiques comme le London Eye, le Tower Bridge et le Palais de Buckingham.</p>
            <p>Vous pouvez également faire du shopping dans les grands magasins de Londres et déguster des plats délicieux dans les restaurants de la ville.</p>
            <p>Alors, préparez-vous à vivre une expérience inoubliable à Londres pendant les vacances de Noël !</p>
        </div>
        <div class="sectionimage">
            <img src="images/londoneye.jpg" alt="Image du London Eye de nuit" />
        </div>
    </div>

    <div class="arrow" onclick="toggleContainers()">&#x2192; Voir plus</div>

    <div id="additionalContainers" class="hidden">
        <div class="container">
            <div class="sectiontext">
                <h2>Les marchés de Noël</h2>
                <p>Les marchés de Noël à Londres sont un incontournable. Vous y trouverez des cadeaux artisanaux, des décorations et des spécialités culinaires.</p>
            </div>
            <div class="sectionimage">
                <img src="images/marche_noel.jpg" alt="Marché de Noël à Londres" />
            </div>
        </div>
        <div class="container">
            <div class="sectiontext">
                <h2>Les spectacles de Noël</h2>
                <p>Assistez à des spectacles de Noël dans les théâtres de Londres, avec des performances qui raviront toute la famille.</p>
            </div>
            <div class="sectionimage">
                <img src="images/spectacle_noel.jpg" alt="Spectacle de Noël à Londres" />
            </div>
        </div>
    </div>
</main>

<?php
// Appel du Pied de Page
require ('footer.php');
?>

<script>

    let currentContainerIndex = 0; // Index du container actuel
    const containers = document.querySelectorAll("#additionalContainers .container");

    function toggleContainers() {
        if (currentContainerIndex < containers.length) {
            containers[currentContainerIndex].classList.remove("hidden");
            currentContainerIndex++;
        } else {
            currentContainerIndex = 0; // Réinitialiser l'index
            containers.forEach(container => container.classList.add("hidden")); // Cacher tous les containers
        }
    }
</script> 

I don’t know if the CSS is needed but just in case here is it :

.container { /*Container du texte et de l'image*/
 display: flex;
 justify-content: space-between;
 margin: 20px auto;
 width: 85%;
 max-width: 1200px;
 gap: 20px;
 background-color: #d2d4e7;
 padding: 10px;
 border-radius: 10px;
 box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
}

.container:hover {
 box-shadow: 0px 6px 20px rgba(0, 0, 0, 0.2);
}

.sectiontext, .sectionimage { /*Sections*/
 flex: 1;
 background-color: #edefff;
 padding: 20px;
 box-sizing: border-box;
 border: 2px solid #464e73;
 border-radius: 10px;
 transition: all 0.3s ease-in-out;
}

.sectiontext:hover, .sectionimage:hover {
 transform: scale(1.02);
 box-shadow: 0px 8px 15px rgba(0, 0, 0, 0.2);
 border-color: #6a82e8;
}

.sectionimage img { /*Image*/
 width: 100%;
 height: 100%;
 object-fit: cover;
 border-radius: inherit;
}

.hidden {
 display: none;
}
.container {
 margin-bottom: 20px;
}
.arrow {
 cursor: pointer;
 font-size: 24px;
 margin: 10px 0;
}

I tried not to touch at the body in css because I have 9 other pages in the same stylesheet so it would change on each I guess.

If you need another details ask me

It would be great if you explain to me what to do !

How to access state, without depending on in with createSelector?

I have a list of entities, each with the property active on it. I want to select those that are active, and to avoid rerendering them each time entities is updated (as an entity which is not active may be added). I figured I could keep track of activeIds, and update it when an entity becomes active.

My issue is, to grab the active entities, I would guess to write something like:

const selectActiveEntities = createSelector(
    (state) => state.entities.items,
    (state) => state.entities.activeIds,
    (entities, activeIds) => activeIds.map(id => entities[id])
)

However, this creates an issue! I believe it will re-render whenever state.entities.items is updated. I, the programmer can identify that the output won’t change unless state.entities.activeIds explicitly changes. How do I achieve dependence solely on state.entities.activeIds?

Why is the JS ‘crypto’ module giving a TypeError?

Background:

I’m using the crypto module to digest a string for hashing and converts the resulting buffer into a string. The resulting function returns a Promise<String>

This is my code:

export default async function hashPassword(unHashedPassword) {

    return crypto.subtle.digest('SHA-256', unHashedPassword)
        .then((hash) => _arrayBufferToBase64(hash))
}

function _arrayBufferToBase64( buffer ) {
    let binary = '';
    const bytes = new Uint8Array( buffer );
    const len = bytes.byteLength;
    for (let i = 0; i < len; i++) {
        binary += String.fromCharCode( bytes[ i ] );
    }
    return btoa( binary );
}

This code lives inside a file called hasher.js in my libs folder of my NextJS app.

The function is then used to hash various bits of data the user has input into a form. I use it like this:

const licenseKey = formData.get('licenseKey')
const hashedPasswordPromise = hashPassword(licenseKey)
hashedPasswordPromise.then(hashedPassword => {
    console.log("Hashed License:", hashedPassword)
})

However, when this section of code runs, I get the following error:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'digest')

What I’ve Tried To Fix It:

Firstly I thought maybe the library was missing. I can confirm that isn’t true as it is indexed by the IDE.

Next, I looked this up and saw that the crypto module will only work in a SecureContext (I was using http at the time). So I then setup nginx with ssl to reverse proxy the requests to next as https. The certificates are added to the keychain and trusted (no warnings on the browser, all secure). However, the issue persists.

Next, I looked at launching next with https enabled. The only results I could find were either exactly what I’ve done with nginx or to use --experimental-https, which is only available in dev and not production, which is no good.

I am stumped. Any suggestions on how to fix this?

Create a direct link that load a page with filter already applied

I need help with javascript code. I ‘m using Elementor Pro and a gallery widget with three filters.

When filtering a gallery on a page using Elementor, the URL doesn’t dynamically update to include specific parameters that reflect the selected filters. Because of this, it’s not possible to create a direct link that would load the page with those filters already applied.
This limitation is due to how Elementor’s filtering system works. It operates dynamically on the front end without affecting or modifying the page’s URL (using AJAX loader).

Maybe some custom JavaScript can help me to achieve such functionality. Is there anyone who can help me with this?​

Chrome DevTools: How to Break when a javascript variable value is changed or accessed

I have been looking for a way to set a breakpoint when a variable’s value is changed. Even better would be to break when a variable’s value is accessed.

Most previous answers to this question are more than 7 years old, and use code and approaches that no longer work. One recent answer said that DevTools will pause whenever the value of a Watch variable changes, but this seems to be false.

I am actually writing an extension and using “world”: “MAIN” in the manifest for my content script, and I want to pause when a variable in the source code is accessed. I don’t know if it’s possible to modify source code that appears in tags, but I hope not, and in any event, that would be too obtrusive.