Capacitor Firebase Firestore onSnapshot returning Promise breaks React useEffect cleanup with “TypeError: e is not a function”

I’ve been banging my head against the wall for days on this one. I have a React app that works perfectly in the browser, but when I build it for iOS using Capacitor, I keep getting this error: TypeError: e is not a function in the minified production code.

I’m using Firebase Firestore real-time listeners to display live data updates in my app. The issue is with how Capacitor’s Firebase plugoin handles the onSnapshot cleanup function.n React, you’re supposed to return a cleanup function from useEffect, right? Like this:

useEffect(() => {
  const unsubscribe = onSnapshot(query, (snapshot) => {
    // handle data
  });
  
  return () => unsubscribe();  // cleanup when component unmounts
}, []);

This works great with the regular Firebase web SDK. But the Capacitor Firebase plugin (@capacitor-firebase/firestore) doesn’t return a function – it returns a Promise that eventually gives you a callback ID. I’ve been trying to wrap this in a way that React will accept, but something breaks during the minification process.

My Wrapper Code
Here’s what I’ve been trying:

import { FirebaseFirestore } from '@capacitor-firebase/firestore';
import { onSnapshot as webOnSnapshot } from 'firebase/firestore';

export function onSnapshot(queryRef, callback, errorCallback) {
  if (isCapacitor()) {
    // This is where things get tricky...
    const unsubscribeHolder = { callbackId: null, isUnsubscribed: false };
    
    // Start the listener (this returns a Promise)
    FirebaseFirestore.addCollectionSnapshotListener(
      {
        reference: queryRef._path,
        compositeFilter: queryRef._compositeFilter
      },
      (event) => {
        if (!unsubscribeHolder.isUnsubscribed) {
          callback(processSnapshot(event));
        }
      }
    ).then(listener => {
      // Store the callback ID for cleanup
      unsubscribeHolder.callbackId = listener.callbackId;
    }).catch(errorCallback);
    
    // Return a function that uses the holder
    return function() {
      unsubscribeHolder.isUnsubscribed = true;
      if (unsubscribeHolder.callbackId) {
        FirebaseFirestore.removeSnapshotListener({ 
          callbackId: unsubscribeHolder.callbackId 
        });
      }
    };
  }
  
  // Browser version works fine
  return webOnSnapshot(queryRef, callback, errorCallback);
}

In development and production, for the browser mode, everything works perfectly. But on iOS in dev mode: Listener starts but cleanup errors, and on iOS in production, it completely breaks with that cryptic TypeError: e is not a function error.

The error happens when the component unmounts and React tries to call the cleanup function. It’s like React’s minifier is doing something to the code that breaks the Promise-to-function bridge I’m trying to create.

I’ve tried:

  1. Returning the unsubscribe function synchronously (still breaks after minification)
  2. Checking typeof unsubscribe === ‘function’ before calling it (the check passes but it still errors!)
  3. Multiple variations of the holder pattern
  4. Different Promise wrappers

I think the problem is that Capacitor’s addCollectionSnapshotListener is inherently async (returns a Promise), but React’s useEffect expects a synchronous function return. When React Scripts minifies everything for production, something about that conversion breaks in a way I can’t debug because it’s all minified.

My questions…

  1. Has anyone actually gotten real-time Firestore listeners working with Capacitor + React in production?
  2. Is there a proper way to bridge Capacitor’s async API to React’s synchronous cleanup pattern?

*Edit:
Environment is:

  {
      "@capacitor-firebase/firestore": "^7.3.1",
      "@capacitor/core": "^7.4.3",
      "firebase": "^11.2.0",
      "react": "^19.0.0",
      "react-scripts": "5.0.1"
    }

**Edit:
The error specifically happens at component unmount when React tries to call the returned cleanup function. The console shows the listener starting fine, but then TypeError: e is not a function when the component unmounts.

Javascript, Radios And Checkbox: How to make a “checked” item work upon opening

Javascript

function changeBorder() {
    const monitor = document.querySelector(".Screen");
    const border = document.getElementById("ScreenBorder");

    border.addEventListener("change", () => { border.checked ? monitor.style.border = "5px solid purple" : monitor.style.border = "1px solid black"; });
}

function changeBG() {
    const screen = document.querySelector(".Screen");
    const screenbackground = document.querySelectorAll('INPUT[name="r"]');

    screenbackground.forEach(radio => {
        radio.addEventListener('click', () => {
            const bgColor = radio.value;
            screen.style.background = bgColor;
        });
    });
}

changeBorder();
changeBG();

CSS

DIV.Screen {
    border: 1px solid black;
    width: 256px;
    height: 256px;
}

HTML

<DIV class="Screen">
</DIV>

<P>
<INPUT type="radio" name="r" value="red" checked>Red
<INPUT type="radio" name="r" value="blue">Blue
<INPUT type="radio" name="r" value="green">Green
</P>

<P><INPUT id="ScreenBorder" type="checkbox" name="checkbox" />Violet Border</P>

This code is a demonstration of two features, the checkboxes and the radios. A black-bordered box appears with two ways for you to change its style. Check on the checkbox to change the border to a 5px solid purple, uncheck it to go back to its initial 1px solid black. Use the radio buttons to change the background color of the box to either red, green or blue.

Pay special attention to the radio buttons. Red is set to “checked”, meaning the box’s color should have been set to red by default upon opening or refreshing this ask page, but it’s not. Instead, there is no color, and in order to make the box turn red, you have to force it by clicking on the red radio dial. Compare that to the checkbox input, where the behavior of toggling between checked and unchecked parameters works as intended.

I’ve always thought that whatever item is labelled “checked” is automatically active, provided the check declarations are made within your Javascript. In the border checkbox toggle example (see border.addEventListener), the original fallback option was set to “initial,” and in this case the box would go back to its 1px solid black style. However, the “initial” keyword did not work, for the entire border disappeared during my test, so I had to explicitly state “1px solid black” in that same line as an insurance measure.

My initial question was on why the “checked” feature works better on checkboxes instead of radios, but to be blunt, I need a better grasp on how the “checked” feature works when it comes to Javascript. How do I rewrite this code so that when I open this web page, the box will have automatically changed color to whatever value was set? If red was “checked”, the box is already red, and so on.

How to render MathJax inside of an SVG

I have a website which includes svg-images which themselves include mathematical formulas that should be rendered using MathJax. As far as I know, this isn’t supported natively (i.e., by just putting the LaTeX-formulas within the SVG.

In the past, I have used the javascript code from this answer by Freddie Page which worked quite nicely for MathJax 2. However, I would now like to switch to MathJax 4 and can’t quite get this code to work again. The following code is my current best try of adapting it:

<!DOCTYPE html>
<html>
    <head>
    <script>
      MathJax = {
        tex: {
            inlineMath: {'[+]': [['$', '$']]}
        }
        startup: {
            ready: () => {
                MathJax.startup.defaultReady();
                MathJax.startup.promise.then(() => {
                    generateTeXinSVGs();
                });
            }
        }
      };
    </script>
    
    <script id="MathJax-script" defer src="https://cdn.jsdelivr.net/npm/[email protected]/tex-svg.js"></script>
        
    </head>
    <body>
    <p>
           An SVG with the formula $a^2+^2=c^2$ inside it:
    </p>
 
    <svg width="360" height="170" viewbox="0 0 360 170">
        <circle cx="80" cy="80" r="40" stroke-width="10" fill="None" stroke="red" />
        <text x="80" y="60">a^2+b^2=c^2</text>          
        <svg class="TeXinSVG" x="80" y="80"><text>a^2+b^2=c^2</text></svg>
    </svg> 
    
    <script type="text/javascript">
        // adapted from: https://stackoverflow.com/a/52011013
        // Define a function that takes LaTeX source code
        // and places the resulting generated SVG in a target SVG element.
        const mathSVG = async function (latex, target) {
          // First create a new element to hold the initial Latex code
          // and eventual MathJax generated SVG. 
          let mathBuffer = document.createElement("div");
          document.body.appendChild(mathBuffer);
        
          // Update the buffer with the source latex.
          mathBuffer.textContent = latex;
          // Get MathJax to process and typeset.
          await MathJax.typeset([mathBuffer]);
        
          var svg = mathBuffer.childNodes[0];
          svg.setAttribute("y", "0pt");
          // Move the generated svg from the buffer to the target element
          target.appendChild(svg);
        };
        
        async function generateTeXinSVGs() {
            listOfSVGs = document.getElementsByClassName("TeXinSVG");
            var i;
            for (i = 0; i < listOfSVGs.length; i++) {
                svgElement = listOfSVGs[i];
                latex = svgElement.children[0].textContent;
                svgElement.innerHTML = "";
                await mathSVG("$" + latex + "$", svgElement);
            }
        }
        </script>   
    </body>
</html>

It works insofar as it adds the output of MathJax to the SVG – however, nothing is displayed. As far as I can see, (part of) the problem seems to be that MathJax 2 created an SVG as top-level element which could then be placed within the SVG, whereas MathJax 4 creates a mjx-container as top-level element which, I guess, cannot be part of an SVG?

If one changes the line

var svg = mathBuffer.childNodes[0];

in the above code to

var svg = mathBuffer.childNodes[0].childNodes[0];

then the first part of the formula (the a^2) gets added to the SVG (and displayed – though slightly cropped). But adding the formula piece-by-piece does not feel like the right direction to me.

Can you help me adapt this code to MathJax 4?
(or maybe there are now better ways of achieving what I want in MathJax 4? Then I am of course also happy to hear about those)

Send array of objects to .NET controller action

I am trying to pass a javascript array of objects to a .NET controller action List<> parameter. Below is my C#

    [HttpPost]
    public bool Import([FromBody]List<Element> element)
    {

        uint srcAddrInt = ConvertIpAddressToUInt(element.SRC_Addr);
        Console.WriteLine($"The IP address {element.add} as an integer is: {int}");

        return true;
    }

Below is the variable I am passing and the ajax call

importData.push({
 ACLId: 11,
 DeviceId: 2,
 ACLGroupId: 5,
 ProtocolId: 27,
 LiftDate: liftDate,
 ActionDate: actionDate,
 RemedyTckt: remedyTicket,
 ITSMTckt: itsmTicket,
/* CommandView: cleanCmdVar,*/
 SRC_Addr: srcAddr,
 SRC_Mask: "0.0.0.0",
 DST_Addr: "0.0.0.0",
 DST_Mask: "255.255.255.255",
 ArinInfo: arin,
 FlagLogInput: 1,
 FlagLog: 0,
 Active: 0

});

var jsonData = JSON.stringify(importData);

$.ajax({
url: '/GAM/ACE/Import',
type: 'POST',             
data: jsonData,
contentType: "application/json; charset=utf-8",
success: function (result) {
    if (result) {                   
        $('#loading-overlay').fadeOut();
    } else {
        alert("Error. Import unsuccessful.");
        $('#loading-overlay').fadeOut();
    }
},
error: function (jqXHR, textStatus, errorThrown) {
    $('#loading-overlay').fadeOut();
    alert("Unable to import data. Error with /GAM/ACE/ImportAce ." + errorThrown);;
}

});

I am not sure what I am doing wrong. The element parameter for the controller is received and shows the objects in the list. But each object’s values are null. None of the data is coming through. I can see the payload coming through correctly. Any suggestions are appreciated

OSM Buildings viewer.remove() and viewer.destroy() not working propperly

Kinda newbie at programming so please bear withe me…

So I am trying to dynamically add and remove objects from the OSMBuildings 3dviewer using Java Script.

Short explaination:
I tried using the .remove() method to no avail… then found the .destroy() method but it also didnt work (In almost all scenarios that i tested i get 0 errors/a completely silent fail and everything just continues without removing the object)

Then after that tried to use the .destroy method + clearing the html div to clear the whole map and just reload all objects except the one that i want to remove but the map starts flashing red when i create a new one (probably because the old one is not cleared completely).

Detailed explaination/rant:
The “documentation” (https://osmbuildings.org/documentation/viewer/api) mentions the .remove() method which doesnt seem to be working no matter what i try (i tried viewer.remove(object itself), i tried using viewer.remove(‘id’ of object), i tried object.remove() etc etc). I even went through the source code just to find:

remove(object) {
   if (object.destroy) {
       object.destroy()
   }
}

i then tried the object.destroy method which also did NOTHING… I didnt even get any error message in any of these tests except for object.remove().

after that i tried to use a rather unsatisfying workaround (as described in the seconnd half of my short explaination) by clearing the div and destroying the map and creating a new one without the object that i want to remove. But that just makes the new map flash red and glitch… I then tried to just delete the div and create a new div with the same name but then OSMBuildings does not seem to find the div at all (my guess since the error message is not really helpful) despite the div definitely existing….

Any advice is highly appreciated.

I am working with Html, JS, and CSS on windows 11 pro using Chrome and Opera to test my page.

i tried too many things to go into detail on all of them but ill attach my current attempt at removing an object.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>3D Map with OSM Buildings</title>
  
  <link href="https://cdn.osmbuildings.org/4.1.1/OSMBuildings.css" rel="stylesheet">
  <script src="https://cdn.osmbuildings.org/4.1.1/OSMBuildings.js"></script>

  <style>
    body {
      margin: 0;
      padding: 0;
    }
  </style>
</head>
<body>

  <div id="map3D" style="width: 950px; height: 450px;"></div>

  <script>
    var map = new OSMBuildings({
      container: 'map3D',
      position: { latitude: 53.111212, longitude: 8.857276 }, 
      zoom: 16,
      minZoom: 13,
      maxZoom: 19,
      attribution: '© Data <a href="https://openstreetmap.org/copyright/">OpenStreetMap</a> © Map <a href="https://osmbuildings.org/copyright/">OSM Buildings</a>'
    });

    map.addMapTiles('https://tile-a.openstreetmap.fr/hot/{z}/{x}/{y}.png');
    map.addGeoJSONTiles('https://{s}.data.osmbuildings.org/0.2/59fcc2e8/tile/{z}/{x}/{y}.json');

  </script>
  <script>

    //var for custom building
    var buildings = [];
    let lon = 53.111;
    let lat = 8.857;
    droneSize = 2;
    let lat1 = lat + 0.00005;
    let lon1 = lon + 0.00005;
    let lat2 = lat + 0.00005;
    let lon2 = lon - 0.00005;
    let lat3 = lat - 0.00005;
    let lon3 = lon - 0.00005;
    let lat4 = lat - 0.00005;
    let lon4 = lon + 0.00005;

    let customBuilding = {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "properties": {
            "height": 15,
            "minHeight": 11,
            "color": "#cc0000"
          },
          "geometry": {
            "type": "Polygon",
            "coordinates": [[
              [lat1, lon1],
              [lat2, lon2],
              [lat3, lon3],
              [lat4, lon4],
              [lat1, lon1]
            ]]
          }
        }
      ]
    };

    //add custom building and store object in buildings array
    buildings.push(map.addGeoJSON(customBuilding, { id: '1' }));
    //remove custom buildings that are in array from map
    for(const building of buildings) {
      console.log(building);
      //different tries to remove building from map
      map.remove(building);
      map.remove({id: '1'});
      map.remove('1');
      map.remove(1);
      building.destroy();
    }
  </script>

</body>
</html>

I have written the jsp,js and servlet for my program but the data is not passed from js to servlet. Below are the code snippet

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>New User Sign Up</title>
    <!-- Bootstrap CSS CDN -->
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
    <link rel="stylesheet" href="loginNewUserSignUp.css" />
</head>
<body>
    <div class="signup-container">
        <div class="signup-header">NEW USER SIGN UP DETAILS</div>
        <form id="signupForm" novalidate>
            <div class="form-row d-flex align-items-center mb-2">
                <label for="userName" class="label-field col-4">Enter User Name</label>
                <input type="text" id="userName" name="userName" autocomplete="off" class="input-field col-7" />
                <span class="asterisk">*</span>
            </div>
            <div class="form-row d-flex align-items-center mb-2">
                <label for="userId" class="label-field col-4">Enter User ID</label>
                <input type="text" id="userId" name="userId" autocomplete="off" class="input-field col-7" />
                <span class="asterisk">*</span>
            </div>
            <div class="form-row d-flex align-items-center mb-2">
                <label for="password" class="label-field col-4">Enter User Password</label>
                <input type="password" id="password" name="password" autocomplete="off" class="input-field col-7" />
                <span class="asterisk">*</span><br>
                
            </div>
            <span class="password-msg">(Atleast one Capital Letter, One Number and One Special Character should be in Password)</span>
            <div class="form-row d-flex align-items-center mb-2">
                <label for="confirmPassword" class="label-field col-4">Confirm User Password</label>
                <input type="password" id="confirmPassword" name="confirmPassword" autocomplete="off" class="input-field col-7" />
                <span class="asterisk">*</span>
            </div>
            <div class="form-row d-flex align-items-center mb-2">
                <label for="email" class="label-field col-4">Enter User Email ID</label>
                <input type="email" id="email" name="email" autocomplete="off" class="input-field col-7" />
                <span class="asterisk">*</span>
            </div>
            <div class="form-row d-flex align-items-center mb-2">
                <label for="mobile" class="label-field col-4">Enter User Mobile No.</label>
                <input type="text" id="mobile" name="mobile" autocomplete="off" maxlength="10" class="input-field col-7" />
                <span class="asterisk">*</span>
            </div>
            <div class="form-row d-flex align-items-center mb-2">
                <label for="address" class="label-field col-4">Enter User Address</label>
                <textarea id="address" name="address" class="input-field col-7" rows="4" wrap="soft"></textarea>
                <span class="asterisk">*</span>
            </div>
            <div class="button-row d-flex justify-content-center mt-3">
                <button type="submit" class="submit-btn">SUBMIT</button>
                <button type="reset" id="resetBtn" class="reset-btn">RESET</button>
                <button type="button" id="closeBtn" class="close-btn">CLOSE</button>
            </div>
        </form>
    </div>

    <script src="loginNewUserSignUp.js"></script>
</body>
</html>

My js file code is —

// 
// Disable right-click on the page
document.addEventListener('contextmenu', event => event.preventDefault());

// Disable tab key and enable enter key to move focus
document.addEventListener('keydown', function(event) {
    if (event.key === 'Tab') {
        event.preventDefault();
    }
    if (event.key === 'Enter') {
        const formElements = Array.from(document.querySelectorAll('#signupForm input, #signupForm textarea'));
        const index = formElements.indexOf(document.activeElement);
        if (index > -1 && index < formElements.length - 1) {
            formElements[index + 1].focus();
            event.preventDefault();
        }
    }
});

const form = document.getElementById('signupForm');

function showError(input, message) {
    alert(message);
    input.focus();
}

function validateNotBlank(input, fieldName) {
    if (!input.value.trim()) {
        showError(input, `The field cannot be Blank: ${fieldName}`);
        return false;
    }
    return true;
}

function validatePassword(input) {
    const value = input.value;
    const hasCapital = /[A-Z]/.test(value);
    const hasNumber = /[0-9]/.test(value);
    const hasSpecial = /[!@#$%^&*(),.?":{}|<>]/.test(value);
    if (!hasCapital || !hasNumber || !hasSpecial) {
        showError(input, "Password must contain at least one Capital Letter, One Number and One Special Character.");
        return false;
    }
    return true;
}

function validateConfirmPassword(passwordInput, confirmInput) {
    if (passwordInput.value !== confirmInput.value) {
        alert("The Password and Confirm Password are not same.");
        confirmInput.focus();
        return false;
    }
    return true;
}

function validateEmail(input) {
    const emailRegex = /^[^s@]+@[^s@]+.[^s@]+$/;
    if (!emailRegex.test(input.value.trim())) {
        showError(input, "Enter valid Email ID");
        return false;
    }
    return true;
}

function validateMobile(input) {
    const mobileRegex = /^[0-9]{10}$/;
    if (!mobileRegex.test(input.value.trim())) {
        showError(input, "Enter a valid Mobile Number");
        return false;
    }
    return true;
}

function validateAddress(input) {
    const words = input.value.trim().split(/s+/).filter(word => word.length > 0);
    if (words.length === 0 || words.length > 4500) {
        showError(input, "Please enter proper Address not more than 4500 words.");
        return false;
    }
    return true;
}

form.addEventListener('submit', function(event) {
    event.preventDefault();
alert("Entering Data");
    const userName = document.getElementById('userName');
    const userId = document.getElementById('userId');
    const password = document.getElementById('password');
    const confirmPassword = document.getElementById('confirmPassword');
    const email = document.getElementById('email');
    const mobile = document.getElementById('mobile');
    const address = document.getElementById('address');

    if (!validateNotBlank(userName, 'User Name')) return;
        if (!validateNotBlank(userId, 'User ID')) return;
        if (!validateNotBlank(password, 'Password')) return;
        if (!validatePassword(password)) return;
        if (!validateNotBlank(confirmPassword, 'Confirm Password')) return;
        if (!validateConfirmPassword(password, confirmPassword)) return;
        if (!validateNotBlank(email, 'Email')) return;
        if (!validateEmail(email)) return;
        if (!validateNotBlank(mobile, 'Mobile')) return;
        if (!validateMobile(mobile)) return;
        if (!validateNotBlank(address, 'Address')) return;
        if (!validateAddress(address)) return;
        alert("Entering Transfer");
        const servletUrl = 'http://localhost:8081/MyTransactionDetails/Servlets/loginNewUserData';
    // Send data to servlet
    fetch(servletUrl, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            userName: userName.value,
            userId: userId.value,
            password: password.value,
            confirmPassword:confirmPassword.value,
            email: email.value,
            mobile: mobile.value,
            address: address.value
        })
        
    })
    
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            alert('Data entered successfully');
            // Clear form
            form.reset();
            // Focus on userName
            userName.focus();
        } else {
            alert('Error: ' + data.message);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        alert('An error occurred during sign up.');
    });
});

My servlet code is as shown below

package Servlets;

import java.io.IOException;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONObject;



import java.sql.ResultSet;
import java.sql.SQLException;
import jakarta.servlet.*;


@WebServlet("/loginNewUserData")
public class loginNewUserData extends HttpServlet {
    private static final long serialVersionUID = 1L;

    // Database connection details
    private static final String DB_URL = "jdbc:mysql://localhost:3306/mytransactiondetails";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "Devi@27032009";

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // CORS headers
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type");
        
        response.setContentType("application/json");
        PrintWriter out = response.getWriter();

        StringBuilder sb = new StringBuilder();
        String line;
        try (BufferedReader reader = request.getReader()) {
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        }
        String requestBody = sb.toString();

        JSONObject jsonRequest = new JSONObject(requestBody);
        String userName = jsonRequest.getString("userName");
        String userId = jsonRequest.getString("userId");
        String password = jsonRequest.getString("password");
        String confirmpwd=jsonRequest.getString("confirmPassword");
        String email = jsonRequest.getString("email");
        String mobile = jsonRequest.getString("mobile");
        String address = jsonRequest.getString("address");

        JSONObject jsonResponse = new JSONObject();

        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection conn =null;
            conn=DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
            
            String newUserIDNo = null,sqlSearchID;
            sqlSearchID="select count(qr_New_User_ID) as totalID from qr_new_user_details";
            PreparedStatement pstmt= conn.prepareStatement(sqlSearchID);
            ResultSet rs=pstmt.executeQuery();
            while (rs.next())
            {
                newUserIDNo=rs.getString("totalID");
                newUserIDNo=newUserIDNo+1;
            }
            
            Date CurDate=new Date();
            SimpleDateFormat sdf=new SimpleDateFormat("dd/mm/yyyy");
            String getCurDate=sdf.format(CurDate);

            String sql = "INSERT INTO qr_new_user_details (qr_New_User_ID, qr_New_User_Name, qr_New_UID, qr_New_UPWD, qr_New_UCPWD, qr_New_User_Email,qr_New_User_Mobile,"
                    + "qr_New_User_Address,qr_New_User_Status,qr_New_User_Create_Date) VALUES (?, ?, ?, ?, ?, ?,?,?,?,?)";
            java.sql.PreparedStatement stmt = conn.prepareStatement(sql);
            stmt.setString(1, newUserIDNo);
            stmt.setString(2, userName);
            stmt.setString(3, userId);
            stmt.setString(4, password);
            stmt.setString(5, confirmpwd);
            stmt.setString(6, email);
            stmt.setString(7, mobile);
            stmt.setString(8, address);
            stmt.setString(9, "Active");
            stmt.setString(10, getCurDate);
            
            int rowsAffected = stmt.executeUpdate();

            if (rowsAffected > 0) {
                jsonResponse.put("success", true);
                jsonResponse.put("message", "Data entered successfully");
            } else {
                jsonResponse.put("success", false);
                jsonResponse.put("message", "Failed to insert data");
            }

            stmt.close();
            conn.close();
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
            jsonResponse.put("success", false);
            jsonResponse.put("message", "Database error: " + e.getMessage());
        }

        out.print(jsonResponse.toString());
        out.flush();
    }
    
    protected void doOptions(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // Handle CORS preflight
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type");
        response.setStatus(HttpServletResponse.SC_OK);
    }
}

<———————————————————->
The above is the code which I wrote for new user details to be entered in the jsp file and validated in js file. After validation the data should be transferred fron js file to the servlet. I am using eclipse ide for the coding. The issue is that the data is not transferred from js file to the servlet.

Google Sign In popup not showing (only showing in FireFox)

I am trying to implement Google Sign In on my page. I am following this documentation.

Here is my code:

function loginWithGoogle() {
  if (!otherUtils.notNullEmptyOrUndefined(cookieUtils.getAuthToken())) {
    google.accounts.id.initialize({
      client_id: "xxxxxx",
      callback: (response) => handleCredentialResponse(response),
      ux_mode: "popup",
    });
    google.accounts.id.prompt();
  }
}

NOTE: Don’t mind the if(...) part – the code goes through it, I checked.

And here is HTML part:

<template>
  <div class="options-container">
    <div id="google-login-button">
      <button @click="loginWithGoogle">google</button>
    </div>
  </div>
</template>

I am using Nuxt 4 btw.

I have a problem where the popup that should appear doesn’t show on Brave, Chrome and Opera. It only shows on Firefox.

enter image description here

What can be the problem?

Changing Delimeter of Multiple Items Returned by a osascript/javascript File Select Dialog

I have a little zsh script I’m coding to run on MacOS. Been a bash/shell scripter for 25+ years, so it hasn’t been all bad. Part of its function is to have the user select a file (or files) from a dialog using this little bit of osascript/javascript:

IMAGES="$(osascript -l JavaScript -e 'a=Application.currentApplication();a.includeStandardAdditions=true;a.chooseFile({withPrompt:"Select Image(s)",multipleSelectionsAllowed:"true"}).toString()')"

The selected files (three in this example) get dumped into the $IMAGES variable with a comma between each of them.

/Users/anderson/Pictures/1890-1899/1898/5-3-1898 John Gansemer & Lena Gansemer (nee Koltes).jpg,/Users/anderson/Pictures/1890-1899/1898/1898 Hans, Mary Anderson Wedding Photo 600dpi.jpg,/Users/anderson/Pictures/1890-1899/1898/1898 Hans. Mary Anderson Wedding Photo.jpg

Is there a way to get the delimiter to be something else (a pipe or something similar) that is less likely to show up in file or folder names that I am grabbing?

I’ve found references across the interwebs to the following the toString with a “.join” function, but I can’t get the syntax right and/or might be barking up the wrong tree anyway.

Thanks,

Bill

Injecting invisible metadata to gmail emails fails for certain gmail account [closed]

I have a chrome extension which appends some base64 metadata to gmail emails before sending them (and keeps the base64 metadata invisible for the user).
This is done through InboxSDK, and works as a charm for every but single account.
Only the emails sent from this account, get base64 metadata stripped off.
It doesn’t appear neither when message is opened in inbox nor sent emails.

I tried following ways of injecting it:

1)
<div style='display:none!important; mso-hide:all; max-height:0; overflow:hidden; font-size:1px; line-height:1px;' class='spx-meta'>${base64Metadata}</div>

2)
<img src="https://yourdomain.com/pixel.gif?policy=${base64Metadata}" width="1" height="1" style="display:none;" alt="">

3)
<span style="color:#ffffff;font-size:1px;">${base64Metadata}</span>

Each of these work on other accounts, but this one sanitizes it for some reason and completely removes it.
Any proven way to send data in email this way?

javascript function force round up the decimal [duplicate]

I looking for java-script function that will force round up the decimal.

for example value = 12.23123 will round to 12.24 .

toFixed() not return the value I want .
I want something like math.ceil but not round up to nearest numeric but to nearest decimal

for example 5.561 , when round 2 decimal will return 5.57 not 5.56

How to preview an image before uploading it? [duplicate]

I’m trying to let users preview an image before uploading it to the server.
I have an HTML , and I want to show a small preview of the selected image right after the user selects it.

I tried using FileReader, but I’m not sure if I’m doing it correctly.
The image is not displaying, or sometimes I get an empty preview.

Here’s my code below. Can someone tell me what I’m doing wrong or how to properly preview an image before upload using JavaScript?

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Image Preview Before Upload</title>
</head>
<body>
  <h2>Upload and Preview Image</h2>
  <input type="file" id="imageInput" accept="image/*">
  <br><br>
  <img id="preview" src="" alt="Image Preview" width="200" style="display:none;">

  <script>
    const imageInput = document.getElementById('imageInput');
    const preview = document.getElementById('preview');

    imageInput.addEventListener('change', function(event) {
      const file = event.target.files[0];
      if (file) {
        const reader = new FileReader();
        reader.onload = function(e) {
          preview.src = e.target.result;
          preview.style.display = 'block';
        }
        reader.readAsDataURL(file);
      }
    });
  </script>
</body>
</html>`

Injecting invisible metadata to gmail emails fails for certain gmail account

I have a chrome extension which appends some base64 metadata to gmail emails before sending them (and keeps the base64 metadata invisible for the user).
This is done through InboxSDK, and works as a charm for every but single account.
Only the emails sent from this account, get base64 metadata stripped off.
It doesn’t appear neither when message is opened in inbox nor sent emails.

I tried following ways of injecting it:

1)
<div style='display:none!important; mso-hide:all; max-height:0; overflow:hidden; font-size:1px; line-height:1px;' class='spx-meta'>${base64Metadata}</div>

2)
<img src="https://yourdomain.com/pixel.gif?policy=${base64Metadata}" width="1" height="1" style="display:none;" alt="">

3)
<span style="color:#ffffff;font-size:1px;">${base64Metadata}</span>

Each of these work on other accounts, but this one sanitizes it for some reason and completely removes it.
Any proven way to send data in email this way?

eBay Subscribe to itemSold notification with RESTful API

I am trying to subscribe to several eBay notifications (itemSold, fixedPriceTransactionEnd, etc.). The users backend server should be informed about every sale. So far I got stuck between the two APIs and tons of documentation but have not seen any other example than MARKETPLACE_ACCOUNT_DELETION. When I call getTopics I only get this along with ESP_test_APP topic. How can I subscribe to the aforementioned topics?

There is a similar unanswered question using the old API here. I am trying to use this SDK. I think they use the ebay api definitions.

2D Perlin Noise function is creating chopped-up uneven rows

I’ve gone about using a (from what I can tell) rather different implementation of 2D Perlin Noise described in this paper by the University of Cambridge:Appendix B – Perlin Noise But the function produces inconsistencies between rows:
Inconsistent 2D Perlin Noise

Here’s my code, just barebones JavaScript in HTML5:

<!-- I've been trying to make functional classic perlin noise for years and this is
     the closest I've come to achieving that goal.

I used this paper:
https://www.cl.cam.ac.uk/teaching/1718/FGraphics/Appendix%20B%20-%20Perlin%20Noise.pdf
-->

<!DOCTYPE html>
<html>
  <canvas id = "canvas" width = "512" height = "512"></canvas>
  
  <script>
    let canvas = document.getElementById("canvas");
    let context = canvas.getContext("2d");
    
    
    const n = 8;
    
    
    const rand_uVec = function () {
      const a = Math.random() * (Math.PI * 2.0);
      return {x: Math.cos(a), y: Math.sin(a)};
    }
    
    const seedArray = function () {
      let s = [];
      for (let x = 0; x < n + 1; x++) {
        s[x] = [];
        for (let y = 0; y < n + 1; y++) s[x][y] = rand_uVec();
      } return s;
    }
    
    const seed = seedArray();
    
    
    function PerlinNoise2D(x, y) {
      const s = Math.floor(x), t = Math.floor(y);
      
      /*
      * (s + 0, t + 0),
      * (s + 1, t + 0),
      * (s + 1, t + 1),
      * (s + 0, t + 1)
      */
      
      // define the grid cell corner coordinates
      const s0 = s + 0, t0 = t + 0,
            s1 = s + 1, t1 = t + 1;
      
      // get the random gradient vectors
      const v00 = seed[s0][t0],
            v10 = seed[s1][t0],
            v11 = seed[s1][t1],
            v01 = seed[s0][t1];
      
      // get the difference between the cell corner and sample point
      const d00 = {x: x - s0, y: y - t0},
            d10 = {x: x - s1, y: y - t0},
            d11 = {x: x - s1, y: y - t1},
            d01 = {x: x - s0, y: y - t1};
      
      
      const dot = function (v0, v1) {
        return v0.x * v1.x + v0.y * v1.y;
      }
      
      const UL = dot(v00, d00),
            UR = dot(v10, d10),
            LR = dot(v11, d11),
            LL = dot(v01, d01);
      
      
      const S = function (t) {
        return 3 * t ** 2 - 2 * t ** 3;
      }
      
      
      // the problem isn't that I'm using an existing x and y variable in these two functions
      const L = function (sx, sy) {
        return LL + S(sx - Math.floor(sx)) * (LR - LL);
      }
      
      const U = function (sx, sy) {
        return UL + S(sx - Math.floor(sx)) * (UR - UL);
      }
      
      
      return L(x, y) + S(y - Math.floor(y)) * (U(x, y) - L(x, y));
    }
    
    
    ImageData.prototype.fragColor = function (x, y, s) {
      this.data[(y * this.width + x) * 4 + 0] = s;
      this.data[(y * this.width + x) * 4 + 1] = s;
      this.data[(y * this.width + x) * 4 + 2] = s;
      this.data[(y * this.width + x) * 4 + 3] = 255;
    }
    
    let noiseTexture = context.getImageData(0, 0, canvas.width, canvas.height);
    for (let x = 0; x < canvas.width; x++) {
      for (let y = 0; y < canvas.height; y++)
        // noiseTexture.fragColor(x, y, Math.random() * 255);
        noiseTexture.fragColor(x, y, PerlinNoise2D(x * (n / canvas.width), y * (n / canvas.height)) * 255);
    } context.putImageData(noiseTexture, 0, 0);
    
    const dataURL = canvas.toDataURL('image/png');
    
    const link = document.createElement('a');
    link.href = dataURL;
    link.download = 'noise.png';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link); // Remove the temporary link
  </script>
</html>

I’ve seen problems like this before with other Perlin Noise functions on Stack Overflow, and I have tried changing around the order of some of the input coordinates, but usually the outcome is an even more chopped up noise graph, whereas I expected something with smoother results.

I would appreciate if any answers could follow the implementation of the paper I’m following, rather than the usually implementation with nested linear interpolation functions (I get that it’s the same concept, I just think mine looks more simplistic). I would also appreciate it if your answers could concern only the basest implementation of Perlin Noise without seed implementation/permutation tables. Thanks!