Using multiple addToSet does not work for multiple arrays in one operation

I have a document with the following fields:

    ...
    firebaseTokens: { type: Map, of: String },
    androidIds: [{ type: String, maxlength: 128 }],
    advertisingIds: [{ type: String, maxlength: 128 }],
    firebaseInstallationIds: [{ type: String, maxlength: 128 }],
    ...

When I want to set all three arrays using $AddToSet at the same time in one operation, only the last array is set.

 let user = {
     _id: userId,
     $set: { [`firebaseTokens.${deviceId}`]: token, },
     $addToSet: { androidIds: deviceId },
     $addToSet: { advertisingIds: advertisingId },
     $addToSet: { firebaseInstallationIds: firebaseInstallationId }
 }
 let options = { new: true, setDefaultsOnInsert: true };
 let userDoc = await UserModel.findByIdAndUpdate(user._id, user, options);

In the above code, only firebaseInstallationIds are set.

Client certificates(Multiple client certificates for single URL) for login in Cypress

I am trying to implement an E2E test using cypress and client cert authentication, and need more than one pair of client certificate to verify different use cases under the same site and don’t know how or if it’s possible to choose specifically one pair at runtime.

We have different client certificates for manager roles and member roles, and we need to pick the corresponding certificate at a test case level or at least at spec level.

Currently cypress allows only one client certificate per URL and this is not satisfying our requirement.

Is it there any way to achieve this using only cypress?

Is it there any alternative known solution that can be used together with cypress to solve this? Looking forward to your reply.

I have successfully configured for one client certificate and successfully logged in. but not able to find a solution for multiple logins with different user ids? Looking forward for a solution

I stored certificates in cert folder and link it in cypress.config file and it worked for a single certificate

HTML injected class through vanilla Javascript for my static site, object fetched from JSON not updating

This is the function that I am working with:

${Id}>const displayCritters = async () => {
    const critters = await fetchCritters();
    let dataDisplay = critters.map((critter) => {

      const { Name, Id, Age, Attributes, ImageInfo } = critter;
      const { Species, Occupation, Personality, Description } = Attributes;
      const { Avatar} = ImageInfo;
      console.log(critter);
      return `
      <div class=Container_${Id}>
        <img src="${Avatar}" alt="They are a ${Species}">
        <p>Name: ${Name}</p>
        <p>Species: ${Species}</p>
        <p>Age: ${Age}</p>
        <p>Occupation: ${Occupation}</p>
        <p>Personality: ${Personality}</p>
        <p>Description: ${Description}</p>
      </div>`;
    }).join("");

As you can see in the block below, Container_undefined is what the classname is.

      <div class="Container_undefined">
        <img src="critterworldcritters00.00_Mason00.00_Mason.png" alt="They are a Frog">
        <p>Name: Mason</p>
        <p>Species: Frog</p>
        <p>Age: 40</p>
        <p>Occupation: Pet Shop Clerk</p>
        <p>Personality: Sassy</p>
        <p>Description: Mason works and lives with Mark at the pet shop.</p>
      </div>

This is the JSON that I am working with:

{
    "Name": "Mason",
    "Age": "40",
    "Id": "000.00",
    "Attributes": {
      "Color": "#5fad55",
      "Species": "Frog",
      "Occupation": "Pet Shop Clerk",
      "Personality": "Sassy",
      "Description": "Mason works and lives with Mark at the pet shop."
    },
    "ImageInfo": {
      "Avatar": "critterworld\critters\000.00_Mason\000.00_Mason.png",
      "Banner": "critterworld\critters\000.00_Mason\000.00_Mason.png"
    }
  }

What is the reason for Container_undefined being the classname?

I tried using other objects instead of ${Id}
That did work.


const displayCritters = async () => {
    const critters = await fetchCritters();
    let dataDisplay = critters.map((critter) => {

      const { Name, Id, Age, Attributes, ImageInfo } = critter;
      const { Species, Occupation, Personality, Description } = Attributes;
      const { Avatar} = ImageInfo;
      return `
      <div class=Container_${Name}>
        <img src="${Avatar}" alt="They are a ${Species}">
        <p>Name: ${Name}</p>
        <p>Species: ${Species}</p>
        <p>Age: ${Age}</p>
        <p>Occupation: ${Occupation}</p>
        <p>Personality: ${Personality}</p>
        <p>Description: ${Description}</p>
      </div>`;
    }).join("");
  
    display.innerHTML = dataDisplay;
}
      <div class="Container_Mason">
        <img src="critterworldcritters00.00_Mason00.00_Mason.png" alt="They are a Frog">
        <p>Name: Mason</p>
        <p>Species: Frog</p>
        <p>Age: 40</p>
        <p>Occupation: Pet Shop Clerk</p>
        <p>Personality: Sassy</p>
        <p>Description: Mason works and lives with Mark at the pet shop.</p>
      </div>

Javascript setInterval and setTimeout giving unexpected results

I have a setInterval with an interval of 4 seconds , which is calling a function fun1. Now for the first Hi to print it is taking 16 seconds which is understandable but now after every 4 seconds I am seeing a “Hi”.

Why there is a no delay of 16 seconds now? I am seeing that 12 second delay only once

function fun1() {
  setTimeout(() => {
    console.log("Hi");
  }, 12000);
}

setInterval(async() => {
  await fun1();
}, 4000);

I tried incrementing value of p every time , to check if fun1() is running only once but , the value is incrementing every time so why there is no delay now. I expect 16 seconds delay after every “Hi”.

reorganise a large array of pixels values in javascript

I have an array of length 28000, its from an image 70×100 pixels, so every 4 values represent a pixel like this [r,g,b,a, ...].

I want to make a grid out this image. A grid of 7 cells in a row, and 10 cells in a column, so I would have 70 cells, 10×10 pixels, with the pixels from the image.

I’m trying to solve this by going from left to right, top to bottom, since this is how the original array was build with the p5js loadPixels function.

I just want to output a new Array, with 10 items, for the 10 lines. Each of these lines are also arrays, with 7 items. Each of these items are arrays with 400 values for the 10×10(pixels)*4(rgba).

note: the originalArray parameter is the 28000 values array.

function cutCapture(originalArray) {

    let lines = [[], [], [], [], [], [], [], [], [], []]
    let rowArray = [[], [], [], [], [], [], []]
    let copyIndex = 0
    let copyRow = 0

    for (let i = 0; i < originalArray.length; i++) {

        let blockIndex = floor(copyIndex / 40)
        let rowIndex = floor(copyRow / 280)
        let lineIndex = floor(i / 2800)

        if (blockIndex < 7) {
            rowArray[blockIndex].push(originalArray[i])
        }

        if (blockIndex >= 7) {
            copyIndex = 0
        } else {
            copyIndex++
        }

        if (rowIndex == 10) {
            lines[lineIndex] = rowArray
            rowArray = [[], [], [], [], [], [], []]
            console.log(rowArray)
            copyRow = 0
        } else {
            copyRow++
        }
    }
    return lines
}

I always end up with an index in some arrays missing like having a few 391 values instead of 400, or the first index of the lines array not filled in, etc.

I can’t get it right. Can someone see a solution and in a more efficient way that I’m trying to solve this?

How to Use google-auth-library with Vite?

When importing library error is thrown in console:

Uncaught TypeError: Class extends value undefined is not a constructor or null.............google-auth-library.js

Here’s a StackBlitz reproduction: https://stackblitz.com/edit/vitejs-vite-1hhasb?file=src%2FApp.jsx&terminal=dev

New to bundlers as Vite so maybe I miss something in docs, but not clear of way to load such a common library.

I believe this question and this question is the same issue but Typescript.

Trouble changing background of input textbox

I’m trying to create a textbox where if you submit the correct answer, the textbox’s background turns green, and red for the incorrect answer. However, nothing seems to happen for both options.

<h3>
  What tree can you hold in your hand?
</h3>
<form>
  <input autocomplete="off" autofocus name="q" placeholder="Answer" type="text">
  <button type="submit">Submit</button>
</form>
<script>
  document.querySelector('form').addEventListener('submit', function(event) {
    //Stuff
    let input = document.querySelector('input[name="q"]');
    let answer = input.value.toLowerCase().trim();

    if (input.timeoutId) {
      clearTimeout(input.timeoutId);
    }

    // Compare with the correct answer
    if (answer === 'palm tree' || answer === 'a palm tree') {
      input.style.backgroundColor = '#00ff00'; // Green for correct answer
      input.timeoutId = setTimeout(function() {
        input.style.backgroundColor = '';
      }, 2000);
    } else {
      input.style.backgroundColor = '#ff0000'; // Red for incorrect answer
      input.timeoutId = setTimeout(function() {
        input.style.backgroundColor = '';
      }, 2000);
    }
    event.preventDefault();
  });
</script>

Bootstrap collapse not working with elements added dynamically in javascript

I’m trying to elements dynamically to my webpage. On each of these elements I would like to add a bootstrap 5 collapse toggle.

dataset.forEach(function(data) {
    const topContainer = document.createElement('div');
    topContainer.classList.add('d-flex', 'justify-content-between', 'collapse-element');

    //topContainer.appendChild(...);

    const bodyContainer = document.createElement('div');
    bodyContainer.classList.add('collapse', 'show');
    bodyContainer.id = data.id;

    //bodyContainer.appendChild(...);

    // Use Bootstrap 5 data attributes for collapsing
    topContainer.setAttribute('data-bs-toggle', 'collapse');
    topContainer.setAttribute('data-bs-target', '#' + bodyContainer.id);
    topContainer.setAttribute('aria-expanded', 'true');
    topContainer.setAttribute('aria-controls', bodyContainer.id);

    parentElement.appendChild(topContainer);
    parentElement.appendChild(bodyContainer);
});

The classes and attributes get added correctly after inspecting the elements, but the functionality doesn’t work. Any idea why?

webkit-media-controls-volume-slider produces a warning about non-passive event listener to a scroll-blocking ‘wheel’

There is a strange problem with audio element in latest Chrome-based browsers (probably in other ones as well, but I did not test). The volume slider of the audio, which is internally rendered as input of type “range” and pseudo attribute “-webkit-media-controls-volume-slider”, produces the warning in developer console when user hovers a mouse over the slider:

[Violation] Added non-passive event listener to a scroll-blocking ‘wheel’ event. Consider marking event handler as ‘passive’ to make the page more responsive.

I do know what is the passive event handlers and how to define them, and hence to eliminate the warning, if it would be my code. The problem is that there is no wheel event listeners assigned explicitly.

Here is a simple test page to reproduce – you can load it locally in a browser (a short sound is attached to enable the audio controls, you can use your own one).

<!DOCTYPE HTML>
<html>
  <body>
  <audio id="main" controls controlsList="nodownload noplaybackrate"></audio>
  </body>
  <script>
  const main = document.getElementById("main");
  main.src = "data:audio/wav;base64,UklGRuQBAABXQVZFZm10IBAAAAABAAIARKwAAIhYAQAC" +
  "AAgAZGF0YcABAACAgICAgICAgICAf39/f39/f39/f39/gICCgoKCgYF/f39/f3+AgH9/f3+AgIGBg" +
  "YGBgYCAgICAgICAgIB+fn19fX1+fn9/f3+AgIKCgYF+fnx8fHyAgIKCgYF+fn5+gICAgH5+fHx9fY" +
  "CAgYGAgH9/f3+AgYCAf3+AgIKCgoKAgHx8fHyAgIGBf398fHx8f3+CgoKCgYGBgYCAgICAgICAf3+" +
  "AgIGBf4B+fn9+gYGCgoGBgIB/f4CAgYGBgYCAgIB/f39/f39/f4CAgYGAgH5+fHx8fH5+f39/f39/" +
  "f3+BgYGBgYGAgH5+fX19fX9/gYGBgX9/fn5/f4CAf39/f39/f39/f4GBgoKCgoCAfn5/f4GBg4OBg" +
  "X9/fn6AgICAf39/f4GBgYGBgYGBgYGAgH9/fn59fX5+f39/f39/f39/f39/f39/f39/f39/gICAgI" +
  "B+fn5+fn5/f4CAgIB/f35+fn5+fn5+f3+AgIGBgYGAgICAgICAgH9/f3+AgIGBgYGAgICAgYGBgYK" +
  "CgoKCgoKCgYGBgYGBgIB+fn19fX1+fn5+fX19fX19fX19fX5+f3+AgICAf39/f4CAgIB/f39/";
  </script>
</html>

Then hover your mouse over the “speaker” sign to open volume slider and look into the log to find the warning.

enter image description here

So, I suppose there is a hidden (not publicly visible) wheel event listener, assigned by the browser itself, and it does this in blocking mode. The question is is there a way to prevent the warning?

I tried to assign my own wheel event listener for the entire document and made it passive, which was confirmed by the developer tools. Yet the warning persisted.

Infinite masonry layout has inconsistent top calculation

I have the following component which calls api on scroll to keep adding images.

It has masonry layout similar to Pinterest. See image below on how it looks vs what I want.

Essentially images with different height, and the layout keeps them properly aligned with consistent margins.

I want the images to be added row by row. This is cos as the api loads data on scroll, I do not want the styling to keep readjusting the image positions.

This could have been styled differently going column by column which is an easy approach.

But is not efficient due to the api loading more data on scroll and images keeps readjusting which is not ideal.

So coming back to displaying images row by row, the following works, somewhat.

But the top calculation doesn’t seems to be accurate. At times is fine.

But quite regularly the calculation is off.

Can see in images below, the top distance between images varies. Whereas I want it to be consistent 16px.

What am I doing wrong with my top calculation? Pls advice. Thanks.

This is taking inspiration from the suggestion here.
https://stackoverflow.com/a/7128902/2840178

import React, {useState, useEffect, useRef, createRef} from 'react';
import axios from 'axios';
import InfiniteScroll from 'react-infinite-scroll-component';
import debounce from 'lodash.debounce';

const Masonry = () => {
  const gutter = 16;
  const [items, setItems] = useState([]);
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(true);

  const [columnsPerRow, setColumnsPerRow] = useState(1);
  const [columnHeights, setColumnHeights] = useState([0, 0, 0, 0]);

  const divRefs = useRef([]);

  const updateColumns = () => {
    const parentContainer = document.getElementById('mason-parent');
    if (parentContainer) {
      const containerWidth = parentContainer.clientWidth;
      const columnWidth = 400;
      const noOfColumnsPerRow = Math.floor(containerWidth / columnWidth);
      const cols = Math.max(1, noOfColumnsPerRow);
      setColumnsPerRow(cols);
      setColumnHeights(Array(cols).fill(0));
    }
  };

  useEffect(() => {
    fetchItems();
    updateColumns();
    window.addEventListener('scroll', handleScroll);
    window.addEventListener('resize', updateColumns);

    return () => {
      window.removeEventListener('scroll', handleScroll);
      window.removeEventListener('resize', updateColumns);
    };
  }, []);

  const fetchItems = async () => {
    try {
      const page = 5;
      const response = await axios.get(`http://localhost:5005/api?page=${page}&perPage=30`);
      const newItems = response.data;

      setItems((prevItems) => [...prevItems, ...newItems]);

      if (newItems.length === 0) {
        setHasMore(false);
      }

      setPage((prevPage) => prevPage + 1);
    } catch (error) {
      console.error('Error fetching data:', error);
    }
  };

  const debouncedFetchItems = debounce(fetchItems, 500);

  const handleScroll = () => {
    const scrollY = window.scrollY || window.pageYOffset;

    if (scrollY + window.innerHeight >= document.documentElement.scrollHeight - 200) {
      debouncedFetchItems();
    }
  };

  const handleImageLoad = (index) => {
    const divRef = divRefs[index];
    if (divRef && divRef.current) {
      const divHeight = divRef.current.clientHeight;
      const columnIndex = index % columnsPerRow;

      const left = (columnIndex * (400 + gutter)) + gutter;
      setColumnHeights((prevHeights) => {
        const newHeights = [...prevHeights];
        const shortestColumnIndex = newHeights.indexOf(Math.min(...newHeights));
        divRef.current.style.top = `${newHeights[shortestColumnIndex]}px`;
        newHeights[shortestColumnIndex] += (divHeight + gutter);

        return newHeights;
      });

      divRef.current.style.left = `${left}px`;
    }
  };

  return (
    <div>
      <div id="mason-parent" style={{ position: "relative", maxWidth: '1680px', marginLeft: 'auto', marginRight: 'auto'}}>
        <InfiniteScroll
          dataLength={items.length}
          next={fetchItems}
          hasMore={hasMore}
          loader={<h4>Loading...</h4>}
          endMessage={<p>No more items</p>}
        >
          {items.map((imageUrl, index) => {
            if (!divRefs[index]) {
              divRefs[index] = createRef();
            }
            return (
              <div key={index} style={{position: 'absolute'}} ref={divRefs[index]}>
                <img src={imageUrl} alt={`Image ${index + 1}`} loading='lazy' onLoad={() => handleImageLoad(index)}/>
              </div>
            );
          })}
        </InfiniteScroll>
      </div>
    </div>
  );
};

export default Masonry;

This is what I want consistently, the top has uniform 16px margins. As indicated by all the red rectangles.
enter image description here

But I end up with inconsistent top as follows intermittently.
enter image description here

How to extend an existing application

is there something like the symfony bundle system in react?

I want to extend an existing application with (installable) code bundles.

Think of an application that can be extended with plugins.

Can you give me an idea if something like that works in react (nextJs)? Is something like that possible with JS?

PLEASE: remember that i want to have an “installable” solution. Not executing code unless a flag (or something like that) is set is not possible!

THANKS FOR ANY HINTS

Why only .find takes into account all elements of .querySelectorAll, and not .forEach?

I’m building something with puppeteer, and because the DOM tree isn’t very intuitive (on purpose I suppose), I have to find elements in a weird way. Here’s the code that works:

    const props = await propertyPage.evaluate(async () => {
      const elements = Array.from(document.querySelectorAll('*'));

      const price = (() => {
        const element = elements.find(div => div.innerHTML?.trim().startsWith('£'))
        if (!element) return null
        return Number(element.innerHTML.replace(/[^d.]/g, ""));
      })();
      const propertyType = (() => {
        const element = elements.find(div => div.textContent?.trim() === 'PROPERTY TYPE')
        if (!element) return null
        return element?.parentNode?.children[1]?.children[1]?.children[0]?.innerHTML;
      })();
      const bedrooms = (() => {
        const element = elements.find(div => div.textContent?.trim() === 'BEDROOMS')
        if (!element) return null
        return Number(element?.parentNode?.children[1]?.children[1]?.children[0]?.innerHTML?.replace(/[^d.]/g, ''))||null;
      })();
      const bathrooms = (() => {
        const element = elements.find(div => div.textContent?.trim() === 'BATHROOMS')
        if (!element) return null
        return Number(element?.parentNode?.children[1]?.children[1]?.children[0]?.innerHTML?.replace(/[^d.]/g, ''))||null;
      })();
      const tenure = (() => {
        const element = elements.find(div => div.textContent?.trim() === 'TENURE')
        if (!element) return null
        return element?.parentNode?.children[1]?.children[1]?.children[0]?.innerHTML;
      })();
      const size = (() => {
        const element = elements.find(div => div.textContent?.trim() === 'SIZE')
        if (!element) return null
        return element?.parentNode?.children[1]?.children[1]?.children[0]?.innerHTML;
      })();

      return { price, propertyType, bedrooms, bathrooms, tenure, size };
   })

Here’s the code that supposed to work, but it doesn’t:

    const props = await propertyPage.evaluate(async () => {
      const elements = Array.from(document.querySelectorAll('*'));

      let price = null;
      let propertyType = null;
      let bedrooms = null;
      let bathrooms = null;
      let tenure = null;
      let size = null;
      elements.forEach((potentialElement) => {
        price = (() => {
          const element =
            (potentialElement as any).dataset?.testid === 'priceQualifier';
          if (!element) return null;
          return potentialElement?.parentNode?.children[1]?.children[0]
            ?.children[0]?.children[0]?.innerHTML;
        })();
        propertyType = (() => {
          const element =
            potentialElement.textContent?.trim() === 'PROPERTY TYPE';
          if (!element) return null;
          return potentialElement?.parentNode?.children[1]?.children[1]
            ?.children[0]?.innerHTML;
        })();
        bedrooms = (() => {
          const element = potentialElement.textContent?.trim() === 'BEDROOMS';
          if (!element) return null;
          return potentialElement?.parentNode?.children[1]?.children[1]
            ?.children[0]?.innerHTML;
        })();
        bathrooms = (() => {
          const element = potentialElement.textContent?.trim() === 'BATHROOMS';
          if (!element) return null;
          return potentialElement?.parentNode?.children[1]?.children[1]
            ?.children[0]?.innerHTML;
        })();
        tenure = (() => {
          const element = potentialElement.textContent?.trim() === 'TENURE';
          if (!element) return null;
          return potentialElement?.parentNode?.children[1]?.children[1]
            ?.children[0]?.innerHTML;
        })();
        size = (() => {
          const element = potentialElement.textContent?.trim() === 'SIZE';
          if (!element) return null;
          return potentialElement?.parentNode?.children[1]?.children[1]
            ?.children[0]?.innerHTML;
        })();
      });

      return { price, propertyType, bedrooms, bathrooms, tenure, size };
    });

In the second case, it seems like elements is just the initial elements like header, footer etc.

I tried waiting for a promise with some time in a timeout, but hasn’t solved the issue.

Any ideas?

Solutions for text tracking on a video?

I want to create a React app that takes a video stream of a poker game I’m playing to save my hands.

I’m trying to capture my hands, the board, and bets.

Maybe there’s a better free OCR someone can reccomend? Or maybe I just need to train tesseract for this specific task?

Things I’ve tried…

  • I have it set up to use Tesseract.js but it isn’t that accuracte. There are also issues when a new hand starts.

  • I’ve looked into the html but I can’t see the hand data.

How can I make a collapsible div?

I tried to make a collapsible div the same way that a <select> acts like. Since you can’t add an <img> into an <option>.

I tried to replicate a “language selection” box. Like this: what I tried to replicate

When you click on the dropdown box a bunch of different languages pop up.

Here is my code:

HTML and JS:

<button class="languageSelect"><img class="selectedLanguageFlag" src="images/language_sk_flag.png" /></button>
<div id="languageContainer" class="languageContainer">
    <button><img src="images/language_cz_flag.png"/></button>
</div>

<script>
var coll = document.getElementsByClassName("languageSelect");
var i;

for (i = 0; i < coll.length; i++) {
    coll[i].addEventListener("click", function () {
        this.classList.toggle("active");
        var content = document.getElementsByClassName("languageContainer");
        if (content.style.display === "block") {
            content.style.display = "none";
        } else {
            content.style.display = "block";
        }
    });
}
</script>

CSS:

.languageSelect {
    overflow: hidden;
    background-color: #6bca56;
    height: 100%;
    width: 100px;
    position: absolute;
    left: 300px !important;
    top: 0 !important;
    border: none;
}

.languageSelect:hover {
    background-color: #5cae4a;
}

.selectedLanguageFlag {
    overflow: hidden;
    width: 45%;
    height: 30%;
    position: relative;
    left: 10px;
    top: 0%;
    display: block;
}

.languageContainer {
    z-index: 2;
    position: absolute;
    background-color: #5cae4a;
    left: 300px !important;
    top: 100px !important;
    width: 100px;
    display: block;
}