VM1186:5 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘call’) Emscripten

I’ve got a really difficult problem.
I have built libusb with emscripten according to https://web.dev/articles/porting-libusb-to-webusb#build_system_and_the_first_test.
That all works great, with the test program provided, only problem I have now is I am trying to use this library with my own custom code but it is not working.

Very rough code
https://gitlab.com/-/snippets/4844863
I am compiling with this command:

    EMCC_DEBUG=1 emcc main.c ./libusb/build/install-web/lib/libusb-1.0.a 

  -I./libusb/build/install-web/include 
  -L./libusb/build/install-web/lib 
  -s USE_PTHREADS=1 
  -s PTHREAD_POOL_SIZE=4 
  -s PROXY_TO_PTHREAD=1 
  -s ALLOW_MEMORY_GROWTH=1 
  -s ASYNCIFY=1 
  -s ENVIRONMENT=web,worker 
  -sASSERTIONS=2 
  --bind 
  -g3 
  -o main.html

Then I am hosting the file, using

const http = require('http');
const fs = require('fs');
const path = require('path');

http.createServer((req, res) => {
  const filePath = path.join(__dirname, req.url === '/' ? '/main.html' : req.url);

  fs.stat(filePath, (err, stats) => {
    if (err || !stats.isFile()) {
      res.writeHead(404, { 'Content-Type': 'text/plain' });
      res.end('404 Not Found');
      return;
    }

    const ext = path.extname(filePath);
    const contentType =
      ext === '.js' ? 'application/javascript' :
      ext === '.wasm' ? 'application/wasm' :
      ext === '.html' ? 'text/html' :
      'application/octet-stream';

    res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
    res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
    res.writeHead(200, { 'Content-Type': contentType });

    fs.createReadStream(filePath).pipe(res);
  });
}).listen(8080, () => console.log('http://localhost:8080'));

When I visit the site, I get this error in chrome:

Hello, World!
(index):146 Found device 0451:e012
(index):146 Tkaksdf
VM1186:5 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'call')
    at methodCaller<(int) => emscripten::val> (eval at __emval_get_method_caller (http://localhost:8080/main.js:5144:29), <anonymous>:5:17)
    at __emval_call_method (http://localhost:8080/main.js:5015:14)
    at imports.<computed> (http://localhost:8080/main.js:4747:24)
    at main.wasm.emscripten::val emscripten::val::internalCall<(emscripten::internal::EM_METHOD_CALLER_KIND)0, emscripten::val, emscripten::val emscripten::val::call<emscripten::val, int&>(char const*, int&) const::'lambda'(emscripten::internal::_EM_METHOD_CALLER*, emscripten::_EM_VAL*, emscripten::internal::_EM_DESTRUCTORS**, void const*), int&>(emscripten::val emscripten::val::call<emscripten::val, int&>(char const*, int&) const::'lambda'(emscripten::internal::_EM_METHOD_CALLER*, emscripten::_EM_VAL*, emscripten::internal::_EM_DESTRUCTORS**, void const*), int&) const (http://localhost:8080/main.wasm:wasm-function[227]:0x264dd)
    at main.wasm.int (anonymous namespace)::CachedDevice::awaitOnMain<int&>(char const*, int&) const::'lambda'()::operator()() const (http://localhost:8080/main.wasm:wasm-function[116]:0x142a7)
    at main.wasm.(anonymous namespace)::em_set_configuration(libusb_device_handle*, int) (http://localhost:8080/main.wasm:wasm-function[114]:0x13a60)
    at main.wasm.libusb_set_configuration (http://localhost:8080/main.wasm:wasm-function[66]:0x7244)
    at main.wasm.usb_get_device (http://localhost:8080/main.wasm:wasm-function[48]:0x19e1)
    at main.wasm.__original_main (http://localhost:8080/main.wasm:wasm-function[49]:0x29c9)
    at main.wasm.main (http://localhost:8080/main.wasm:wasm-function[50]:0x2d2c)

No sure why, but it stops working in the function libusb_set_configuration
just wondering if anyone has any experience with this or could help guide me on how to debug this type of stuff. Thanks.

How can I play sound with Toast in React?

I need to play a Sound together with a Toast in React. However, the Sound does not play if there is no user interaction in JavaScript. Is there a way to solve this?
This is my code.

const [audioRef] = useState(new Audio("https://firebasestorage.googleapis.com/v0/b/deligo-9f8b3.firebasestorage.app/o/audio%2FOrder_Alert.mp3?alt=media&token=c62014d6-3f2a-4cb9-a4cc-8109a53536d5"));

useEffect(() => {
  audioRef.volume = 0.8;
  audioRef.loop = true;
}, [audioRef]);

const action = () => {
  const button = document.createElement("button");
  button.style.display = "none";
  document.body.appendChild(button);
  button.addEventListener("click", () => {
    audioRef.play().catch(console.error);
  });
  button.click();
  document.body.removeChild(button);

  toast.success("Hi, there. New order just landed!", {
    position: "bottom-right", 
    autoClose: 5000,
    className: "custom-toast",
    progressClassName: "!bg-gradient-to-r from-blue-500 to-purple-500",
    icon: <img src="https://res.cloudinary.com/djjovgwyk/image/upload/v1739515599/photo_2025-02-14_08-37-33_fyib4y.png" />,
  });
}

Loop thru json file for specific data value in NodeJS [duplicate]

I am trying to loop thru a JSON file and only print out a specific value.

This is my example JSON data and I am wanting to print of every market_hash_name

{
"items": [
    { "market_hash_name": "sg-553-danger-close", "exterior": "factory new" },
    { "market_hash_name": "famas-commemoration", "exterior": "field-tested" },
    { "market_hash_name": "sawed-off-spirit-board", "exterior": "well-worn" }
  ]
}

This is my app.js file. I am just stuck on how to print the value I am after.

import { readFile } from 'fs/promises';

const data = JSON.parse(await readFile("item_names.json", "utf8"));

console.log(data)

Expected result

market_has_name: 'sg-553-danger-close'
market_has_name: 'famas-commemoration'
market_has_name: 'sawed-off-spirit-board'

Is there a way to make Google Chrome open links with certain protocols in a new window?

I am using Google Chrome and Google Business suite for my email. I have registered a custom protocol handler for all mailto links in the javascript console from the business suite page using the following code.

navigator.registerProtocolHandler("mailto", 
                                 "https://mail.google.com/mail/u/1/?extsrc=mailto&url=%s", 
                                 "Business Email");

This works just fine as far as the protocol handling is concerned. When a link is clicked, a composition window is opened using the GSuite email.

But, when I click a mailto link, the tab that is currently in use is navigated away from in favor of the composition window. I’d greatly prefer if mailto links opened in a new window and left the tab containing the link unchanged.

Is there a Chrome setting or a piece of code I can run that will force Chrome to always open mailto links in a new window?

I know I can middle click or right click and choose new window, but I’m hoping there’s a solution that makes it automatic.

After five successful POSTs, subsequent requests return 500 with missing CORS headers in production (Vue 2 + Axios + Java/Springboot))

I’m working with Vue 2 and Axios; in production the browser shows “No Access-Control-Allow-Origin” after the sixth or tenth POST request to /api/patients, and the server returns 500 and the user needs to relogging. Locally I fired fifteen consecutive requests—both from the UI and via Postman—without reproducing the error, even with the full 50 kB payload and with a reduced 5 kB version. On the front end I’ve confirmed that headers and tokens are identical on every attempt, there’s no caching or service worker interference, and my Axios interceptor isn’t altering the request. Our backend team has also reviewed their CORS configuration, run stress tests against this same endpoint, and reports everything functioning correctly on their side. Given this, I’m unsure whether the fix should come from my code, from the backend (e.g., ensuring CORS headers are sent even on 500 responses), or if it should be escalated to infrastructure/support

error message when DriveApp.getFolderByID is used

I constantly get an error message when trying to implement DriveApp.getFolderByID. My
partial code is:

'function myFunction() {
var files = DriveApp.getFolderById("https://drive.google.com/drive/folders/1H- 
ZCY71Ej3a7F_cUZ4wmSDc-WIz9gRxl?usp=drive_link
").getFiles()
while (files.hasNext()) {
var file = files.next();'

This is partial code to auto-import a number of google sheets rows at a time to another sheet in the same spreadsheet. However I get this error message. I have searched google
workspace to see if the DriveApp function was still viable and not found to the contary. I get this error message – “Exception: Unexpected error while
getting the method or property getFolderById on object DriveApp.myFunction @ Learning
Auto Import.gs:2” when I run the code. enter code hereHelp Please

How often is a TURN server needed for P2P file transfer?

I am building an app that also has a feature of p2p file transfer. The stack used is react + next.js using socket.io. File transfer works perfectly on home network but if i have 2 devices on 2 networks(regular home network ISPs) the ICE fails. AI keeps telling me i need to use a TURN server. I am hosting one so it wouldn’t be a problem but i just can’t get my mind around having to use a TURN server for each transfer. I can provide logs if needed. Thanks guys!

send page

'use client';

import { useEffect, useRef, useState } from 'react';
import { socket, registerDevice, sendOffer, sendCandidate } from '@/lib/socket';

export default function SendPage() {
    const [receiverId, setReceiverId] = useState('');
    const [status, setStatus] = useState('Waiting...');
    const fileInputRef = useRef<HTMLInputElement>(null);
    const peerConnectionRef = useRef<RTCPeerConnection | null>(null);
    const dataChannelRef = useRef<RTCDataChannel | null>(null);

    const senderDeviceId = 'abc123';

    useEffect(() => {
        registerDevice(senderDeviceId);

        async function createConnection(file: File, receiverDeviceId: string) {
            const peerConnection = new RTCPeerConnection({
                iceServers: [{ urls: "stun:stun.l.google.com:19302" }]
            });

            peerConnectionRef.current = peerConnection;

            const dataChannel = peerConnection.createDataChannel("fileTransfer");
            dataChannelRef.current = dataChannel;

            dataChannel.onopen = () => {
                setStatus("Sending file...");
                sendFile(file);
            };

            peerConnection.onicecandidate = (event) => {
                if (event.candidate) {
                    sendCandidate(receiverDeviceId, event.candidate);
                }
            };

            peerConnection.onicegatheringstatechange = () => {
                if (peerConnection.iceGatheringState === "complete" && peerConnection.localDescription) {
                    sendOffer(senderDeviceId, receiverDeviceId, peerConnection.localDescription);
                    setStatus("Offer sent. Waiting for answer...");
                }
            };

            peerConnection.oniceconnectionstatechange = () => {
                console.log("ICE connection state:", peerConnection.iceConnectionState);
            };

            peerConnection.onconnectionstatechange = () => {
                console.log("Connection state:", peerConnection.connectionState);
            };

            const offer = await peerConnection.createOffer();
            await peerConnection.setLocalDescription(offer);
        }

        function sendFile(file: File) {
            const chunkSize = 16384;
            const reader = new FileReader();
            let offset = 0;

            dataChannelRef.current?.send(JSON.stringify({
                type: "metadata",
                filename: file.name,
                filetype: file.type,
                size: file.size
            }));

            reader.onload = (e) => {
                if (e.target?.readyState !== FileReader.DONE) return;
                if (e.target.result && dataChannelRef.current) {
                    dataChannelRef.current.send(e.target.result as ArrayBuffer);
                    offset += (e.target.result as ArrayBuffer).byteLength;
                    if (offset < file.size) {
                        readSlice(offset);
                    } else {
                        setStatus("File sent successfully!");
                    }
                }
            };

            reader.onerror = () => {
                console.error("Error reading file");
                setStatus("File read error");
            };

            function readSlice(o: number) {
                const slice = file.slice(o, o + chunkSize);
                reader.readAsArrayBuffer(slice);
            }

            readSlice(0);
        }

        const clickHandler = () => {
            const file = fileInputRef.current?.files?.[0];
            if (!file || !receiverId) {
                setStatus("Missing file or device ID");
                return;
            }
            createConnection(file, receiverId);
        };

        document.getElementById("connectBtn")?.addEventListener("click", clickHandler);

        socket.on("receive_answer", async ({ answer }) => {
            const pc = peerConnectionRef.current;
            if (!pc) return;
            if (pc.signalingState === "have-local-offer") {
                await pc.setRemoteDescription(new RTCSessionDescription(answer));
            } else {
                console.warn("Ignoring answer: unexpected signaling state", pc.signalingState);
            }
        });

        socket.on("ice_candidate", ({ candidate }: { candidate: RTCIceCandidateInit }) => {
            if (peerConnectionRef.current) {
                peerConnectionRef.current.addIceCandidate(new RTCIceCandidate(candidate));
            }
        });

        return () => {
            document.getElementById("connectBtn")?.removeEventListener("click", clickHandler);
        };
    }, [receiverId]);

    return (
        <div style={{ fontFamily: 'sans-serif', margin: '2em' }}>
            <h1>Send File</h1>
            <label>
                Receiver Device ID:{' '}
                <input
                    type="text"
                    value={receiverId}
                    onChange={(e) => setReceiverId(e.target.value)}
                />
            </label>
            <br />
            <label>
                Select File: <input type="file" ref={fileInputRef} />
            </label>
            <br />
            <button id="connectBtn">Send File</button>
            <p>{status}</p>
        </div>
    );
}

receive page

'use client';

import { useEffect, useRef, useState } from 'react';
import { socket, registerDevice, sendAnswer, sendCandidate } from '@/lib/socket';

export default function ReceivePage() {
    const [deviceId, setDeviceId] = useState('Loading...');
    const [status, setStatus] = useState('Waiting for offer...');
    const peerConnectionRef = useRef<RTCPeerConnection | null>(null);
    const receivedChunksRef = useRef<Uint8Array[]>([]);
    const receivedSizeRef = useRef(0);
    const metadataRef = useRef<{ name: string; type: string; size: number } | null>(null);

    useEffect(() => {
        function generateRandomId(length = 6): string {
            const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
            return Array.from({ length }, () => chars[Math.floor(Math.random() * chars.length)]).join('');
        }

        const receiverDeviceId = generateRandomId();
        setDeviceId(receiverDeviceId);
        registerDevice(receiverDeviceId);

        socket.on("receive_offer", async ({ sender, offer }: { sender: string; offer: RTCSessionDescriptionInit }) => {
            setStatus("Offer received. Creating answer...");

            const peerConnection = new RTCPeerConnection({
                iceServers: [{ urls: "stun:stun.l.google.com:19302" }]
            });
            peerConnectionRef.current = peerConnection;

            peerConnection.oniceconnectionstatechange = () => {
                console.log("ICE connection state:", peerConnection.iceConnectionState);
            };

            peerConnection.onconnectionstatechange = () => {
                console.log("Connection state:", peerConnection.connectionState);
            };

            peerConnection.ondatachannel = (event) => {
                const channel = event.channel;

                channel.onmessage = async (event) => {
                    if (typeof event.data === "string") {
                        try {
                            const msg = JSON.parse(event.data);
                            if (msg.type === "metadata") {
                                metadataRef.current = {
                                    name: msg.filename,
                                    type: msg.filetype,
                                    size: msg.size
                                };
                                receivedChunksRef.current = [];
                                receivedSizeRef.current = 0;
                                setStatus(`Receiving ${msg.filename} (${msg.size} bytes)`);
                            }
                        } catch (e) {
                            console.warn("Invalid metadata JSON");
                        }
                    } else {
                        const chunk = event.data instanceof Blob
                            ? new Uint8Array(await event.data.arrayBuffer())
                            : new Uint8Array(event.data);
                        receivedChunksRef.current.push(chunk);
                        receivedSizeRef.current += chunk.byteLength;

                        if (metadataRef.current && receivedSizeRef.current >= metadataRef.current.size) {
                            const blob = new Blob(receivedChunksRef.current, { type: metadataRef.current.type });
                            const a = document.createElement("a");
                            a.href = URL.createObjectURL(blob);
                            a.download = metadataRef.current.name;
                            a.click();
                            setStatus("File received and downloaded!");
                        }
                    }
                };

                channel.onopen = () => {
                    setStatus("Data channel open. Receiving file...");
                };
            };

            peerConnection.onicecandidate = (event) => {
                if (event.candidate) {
                    sendCandidate(sender, event.candidate);
                }
            };

            await peerConnection.setRemoteDescription(new RTCSessionDescription(offer));
            const answer = await peerConnection.createAnswer();
            await peerConnection.setLocalDescription(answer);
            sendAnswer(sender, answer);
            setStatus("Answer sent. Waiting for file...");
        });

        socket.on("ice_candidate", ({ candidate }: { candidate: RTCIceCandidateInit }) => {
            if (peerConnectionRef.current) {
                peerConnectionRef.current.addIceCandidate(new RTCIceCandidate(candidate));
            }
        });
    }, []);

    return (
        <div style={{ fontFamily: "sans-serif", margin: "2em" }}>
            <h1>Receive File</h1>
            <p>Your device ID: <strong style={{ color: "#333" }}>{deviceId}</strong></p>
            <p>{status}</p>
        </div>
    );
}

Why is “onload” event triggered early? – GitHub Pages loading screen woes

I’m not a developer and I was not built to write code! I’m using GitHub pages to host a very simple site with a very chunky pdf.

I want the site to land on a loading screen which disappears when the pdf is visible, but the loading screen always disappears almost instantaneously, leaving a blank grey screen on the PDF for about seven seconds before it finally loads.

Here’s the code:

<div id="preloader">
        <div class="loader">
            <Img src="loadingscreentest.png"></Img>
            </div>
    </div>



<div class="content">
    <iframe src="InProgTest5.pdf#toolbar=0&navpanes=0&scrollbar=0&frameBorder=0&view=FitH"  type='application/pdf' onload="killloadscreen()"></iframe> 
</div>



<script>
    function killloadscreen(){
        const preloader = document.getElementById('preloader'); 
        const content = document.getElementById('content');
    preloader.style.display = 'none'; 
    content.style.display = 'block'; 
    }
</script>

I also tried event listeners with window.onload and DOMContentLoaded to hide the loading screen and show the content, but these bore the same results (or worse, with no loading screen showing up at all). I searched around the internet for clues and fixes and tried a few different things to no avail. One insight I found which I fear could be the answer is that there could be interference from the service being used to host the code (Pages, in my case). I’ve been informed that Pages is intended for static websites, so maybe it was always liable to disagree with moving parts like events and scripts? I know very little about this stuff.

Anyway, is there a solvable reason the onload event is triggered before everything is fully loaded? Or is there a way to determine for certain when the contents of the pdf become visible? Or is the code itself wrong? Or perhaps I need a workaround like something that can detect the color of a given pixel behind the loading screen (that seems flimsy to me, but I’m grasping at straws)? If hosting is likely the issue, I’ll absolutely look for a different platform.

Thanks for reading! Any help is appreciated. I am relying on this PDF, and I’m afraid having it blank without a loading screen (or something) is not an option!

Genre paths won’t load in deployed website on Github pages and netlify

When I use my website on github pages it seems to work, but the “genre” paths get me a 404 error from Github. I also used this in netlify and i get the same result. If I click on a genre, it tells me that the page doesn’t exist. And if I press the back button on a 404 page, pages that seem to work also turn into 404 errors. Typing in a link of any page will also give a 404 error, but navigating to those pages (Movies, TV shows, anime) through the site itself seems to work. Everything works as it should if I run it locally using npm run dev/preview, so I’m really lost. Also I want to know if there’s a way to remove /website2/ as the link in github-pages deployments. The website (https://arjunr12345.github.io/website2/) also becomes a blank white screen if I add https://arjunr12345.github.io as homepage in package.json. Even if I try removing “/website2/” from the link manually github just gives me a 404 error again. I tried following the instrucions from here: https://github.com/rafgraph/spa-github-pages, but even after that the problem persists.

Links:
Site: https://arjunr12345.github.io/website2/
Repo: https://github.com/arjunr12345/website2

Amplify OAUTH provider only call with 1 scope

I have setup an OAUTH provider with Amplify (LinkedIn) but the URL called contains only 1 scope even though my scope array contains several in the configuration. Is it possible to specify to Amplify the scopes we want to include specifically?

amplify_outputs.json:

{
  "auth": {
    "user_pool_id": "eu-west-3_[REDACTED]",
    "aws_region": "eu-west-3",
    "user_pool_client_id": "[REDACTED]",
    "identity_pool_id": "eu-west-3:[REDACTED]",
    "mfa_methods": [],
    "standard_required_attributes": [
      "email"
    ],
    "username_attributes": [
      "email"
    ],
    "user_verification_types": [
      "email"
    ],
    "groups": [],
    "mfa_configuration": "NONE",
    "password_policy": {
      "min_length": 8,
      "require_lowercase": true,
      "require_numbers": true,
      "require_symbols": true,
      "require_uppercase": true
    },
    "oauth": {
      "identity_providers": [],
      "redirect_sign_in_uri": [
        "http://localhost:3000/dashboard"
      ],
      "redirect_sign_out_uri": [
        "http://localhost:3000/"
      ],
      "response_type": "code",
      "scopes": [
        "phone",
        "email",
        "openid",
        "profile",
        "aws.cognito.signin.user.admin"
      ],
      "domain": "[REDACTED].auth.eu-west-3.amazoncognito.com"
    },
    "unauthenticated_identities_enabled": true
  },
  "version": "1.4"
}

Call API:

export const registerWithLinkedIn = async () => {
  await signInWithRedirect({
    provider: {
      custom: 'LinkedIn'
    }
  });
}

URL called:

https://www.linkedin.com/oauth/v2/authorization?client_id=[REDACTED]&redirect_uri=[REDACTED].auth.eu-west-3.amazoncognito.com%2Foauth2%2Fidpresponse&scope=openid%2Cemail&response_type=code&state=...

Show validations errors in inertia

I tried to show Validation Errors in template, as the code below it just shows the errors of success and failed, but if i submit the form without write anything, it doesn’t show any message of validation errors, how can i solve it ?

enter image description here

public function edit() {

    return Inertia::render('Settings', [

        'success' => session('success'),

        'failed' => session('failed'),
        
    ]);

}

public function update(Request $request) {

    $request->validate([

        'oldPassword' => 'required|string',

        'newPassword' => 'required|string|min:8',

    ]);

    $userData = User::findOrFail(auth()->id());

    if(!Hash::check($request->oldPassword, $userData->password)) {

        return redirect()->back()->with([

            'failed' => 'Invalid Password !'

        ]);

    }

    $userData->update([

        'password' => Hash::make($request->newPassword),

    ]);

    return redirect()->back()->with([

        'success' => 'Successfully Updated Password'

    ]);

}

Prisma Client Not Generating in Next.JS (or at least type definitions)?

I am using next.js with ts, prisma, and neon. I am trying to create a webhook for Clerk, when a user is created, to take that information and add it to my database.

if (evt.type === 'user.created'){
      console.log("User Created Event Fired!!")
      try {
        const newUser = await prisma.user.create({
      
        id: evt.data.id as string,
        email: evt.data.email_addresses[0]?.email_address,
        name: `${evt.data.first_name || ''} ${evt.data.last_name || ''}`.trim(),

      
    });
    console.log(`User created in database: ${evt.data.id}`);
    return new Response('Create User Webhook received', { status: 200 })
}catch (err) {
  console.error('Error verifying webhook:', err)
  return new Response('Error verifying webhook', { status: 400 })
}}

The schema looks correct:

model User {
  id            String           @id @unique
  clerkId       String           @unique
  email         String           @unique
  name          String
  gbp           GBP[]
  subscription  SubscriptionType @default(FREE)
  createdAt     DateTime         @default(now())
  updatedAt     DateTime         @updatedAt
}

I have run prisma migrate dev , prisma db push, prisma generate, and just about every other command that I thought would transfer over the schema accurately to the client.

But no matter what I do, the error returns:

entInvalid `prisma.user.create()` invocation:

{
  id: "user_29w83sxmDNGwOuEthce5gg56FcC",
  ~~
  email: "example@example.org",
  name: "Example Example",
? data?: UserCreateInput | UserUncheckedCreateInput
}

Unknown argument `id`. Available options are marked with ?.er code here

Any ideas? I am getting ready to trash Prisma for something else because I just cannot get this figured out.

React 19: Component rendered with ReactDOM.createRoot inside useEffect fails to appear on initial load (worked in React 18)

I’m migrating an app from React 18.3.1 / React-DOM 18.3.1 to React 19.1.0 / React-DOM 19.1.0.
With React 18 the code below rendered an EditView component into every DOM element that SurveyJS inserts with the class .editViewContainer.
After upgrading to React 19 nothing shows up the first time the survey is opened; the containers stay empty. When the survey is reopened later, the component appears but behaves unpredictably.

ComponentCollection.Instance.add({
  name: "geometry",          // new question type
  title: "Geometry",         // label in toolbox
  questionJSON: {
    type: "html",
    html: "<div class='editViewContainer'></div>", // placeholder for React
  },
});

// 2 – React code that hydrates those placeholders ---------------------------
const rootMap = React.useRef(new Map());

React.useEffect(() => {
  // Find (possibly many) <div class="editViewContainer"> nodes SurveyJS just wrote
  const containers = Array.from(document.querySelectorAll(".editViewContainer"));

  if (showEditView.show) {
    // Create a root for each *new* container
    containers.forEach((container) => {
      if (!rootMap.current.has(container)) {
        const root = ReactDOM.createRoot(container);
        rootMap.current.set(container, root);

        root.render(
          <EditView
            key={editViewKey}
            app={props.app}
            model={editModel}
            observer={props.localObserver}
            surveyJsData={surveyJsData}
            resetView={resetEditView}
            currentQuestionTitle={currentQuestionTitle}
            currentQuestionName={currentQuestionName}
            onSaveCallback={handleOnComplete}
            ref={editViewRef}
            toolbarOptions={showEditView.toolbarOptions}
            area={area}
            price={price.toFixed(2)}
            geofencingWarningToolbar={geofencingWarningToolbar}
            drawnGeometryMap={drawnGeometryMap}
            geometryValidMap={geometryValidMap}
          />
        );
      }
    });

    // Re-render existing roots whose container is still in the DOM
    rootMap.current.forEach((root, container) => {
      if (containers.includes(container)) {
        root.render(
          /* …same <EditView> props as above… */
        );
      }
    });
  }
}, [
  showEditView,
  editViewKey,
  props.app,
  editModel,
  props.localObserver,
  surveyJsData,
  currentQuestionTitle,
  currentQuestionName,
  handleOnComplete,
  editViewRef,
  showEditView.toolbarOptions,
  area,
  price,
  geofencingWarningToolbar,
  drawnGeometryMap,
  geometryValidMap,
]);

Expected behaviour (React 18.3.1)
When the SurveyJS form is opened for the first time, every .editViewContainer immediately shows .

Actual behaviour (React 19.1.0)
On the first open the placeholders stay empty.
After closing and reopening the form (state change that triggers the same useEffect), sometimes appears but its internal state is broken (toolbar buttons disabled, geometry validation not firing, etc.).

What I tried / research so far
Verified that containers is not empty on the first useEffect run (the nodes exist in the DOM).

Replaced ReactDOM.createRoot → ReactDOM.render (deprecated) as a test → still empty in React 19.

Tried moving the logic to useLayoutEffect → no change.

Wrapped the first render in flushSync → no change.

Searched React 19 release notes for breaking changes around external roots (only found the new suspense defaults, which don’t seem related).

Environment
library working failing
react 18.3.1 19.1.0
react-dom 18.3.1 19.1.0
survey-core survey-react-ui”: “^1.9.113

Question

Did React 19 introduce a change that prevents rendering into DOM nodes created outside React (e.g., by SurveyJS) via ReactDOM.createRoot?
If so, what is the correct pattern in React 19 for attaching a component tree to elements that a third-party library inserts after the initial mount?

Any pointers to migration docs, work-arounds, or an explanation of why the first render is skipped would be greatly appreciated.

How can I split a string in characters or short html elements in javascript

I would like to split a string containing html snippets in characters and the elements.

let str = 'wel<span class="t">come</span> to all'
console.log("split attempt " +JSON.stringify('wel<span class="t">come</span> to all'.split(/(<.*?>)|/)));
                                                                                           ^^^^^^^^^^

giving me:

split attempt ["w",null,"e",null,"l","<span class="t">","c",null,"o",null,"m",null,"e","</span>"," ",null,"t",null,"o",null," ",null,"a",null,"l",null,"l"]

By filtering out the null, I get what I want:

split attempt ["w","e","l","<span class="t">","c","o","m","e","</span>"," ","t","o"," ","a","l","l"]

But is there some smart way in the regexp to filter out html elements (or other specific sequences) and split the rest in the vanilla character by character way?

Change default width of bootstrap modal popup in CSHML?

I’ve been searching for a way to increase the width of the modal popup in my cshtml, but haven’t been able to. I tried the suggestions in this SO question, but none worked.

Here’s my code. Doesn’t matter what changes I make to the CSS, the popup will always have a width of 300px: https://i.sstatic.net/82F2mgrT.png. Even when I change the div width within the modal_dialog div, it will just show the horizontal scrollbar.

@page
@model Products.Pages.IndexModel
@{
}
<br />
<br />
<div id="productsContainer">
    @foreach (var product in Model.availableProducts)
    {
        <div style="float: left;display: inline-block; vertical-align: top; border: 1px solid #ececec">

            <div style="height: 280px">
                <button class="openProductModal" data-product-id="@product.ProductId" data-price="@product.Price"
                        data-name="@product.ProductName" data-prepayment="@product.Prepayment"
                style="border:none; background:none; padding:0;">
                    <img src="@product.ImageUrl" alt="Product Image" width="260" style="padding: 10px">
                </button>
            </div>
            <div style="float: left;height: 60px">
                <div>@product.ProductName</div>
            </div>

            <div>$@product.Price</div>
        </div>
    }
</div>
<div id="modal_dialog" class="modal-dialog modal-lg" style="width: 1000px; border: 1px solid red;display: none">
    <div>
        Ready to pick up
    </div>
    <div>
        Item: <span id="name"></span>
    </div>
    <div>
        $<span id="price"></span>
    </div>
</div>

<script type="text/javascript">
    $("#productsContainer").on("click", ".openProductModal", function() {
      var productId = $(this).data("product-id");
      var price = $(this).data("price");
      var name = $(this).data("name");
      var prepayment = $(this).data("prepayment");
      $("#price").text(price);
      $("#selectedProductId").text(productId);
      $("#Prepayment").text(prepayment);
      $("#name").text(name);
      $("#modal_dialog").dialog({
        buttons: {
          Close: function() {
            $(this).dialog('close');
          }
        },
        modal: true
      });
    });
</script>