ReactGrid Popover Input Field Not Receiving Focus Upon Opening

enter image description here

In the image as you can see i have added a Popover on the react grid
lib – @silevis/reactgrid

I’m working with ReactGrid and have implemented a custom cell renderer that opens a popover containing input fields for editing cell values. However, when the popover opens, the input fields inside it do not receive focus as expected. Instead, the focus seems to remain on the grid, preventing user interaction with the inputs

What I’ve Tried:

Using useRef to reference the input elements and calling .focus() on them inside a useEffect hook when the popover opens.

Blurring the grid’s internal focus element (.rg-hidden-element) before focusing the input.

Wrapping the popover content in a ReactDOM.createPortal to render it outside the grid’s DOM hierarchy.

Despite these attempts, the input fields still do not receive focus when the popover opens.

Expected Behavior:

When the popover opens, the first input field inside it should automatically receive focus, allowing the user to start typing immediately.

Actual Behavior:

The input fields inside the popover do not receive focus upon opening. The focus remains on the grid, and the user must manually click on the input field to start typing.

useEffect(() => {
    if (showModal) {
        const rgHidden = document.querySelector(".rg-hidden-element") as HTMLElement;
        rgHidden?.blur();
        setTimeout(() => inputRef.current?.focus(), 0);
}
}, [showModal]);

How can I ensure that the input field inside the popover receives focus automatically when the popover opens in ReactGrid?

How to fix ‘TypeError: undefined is not a function’ in JavaScript? [closed]

Goal:
I’m trying to call a function in my JavaScript code, but I keep getting the error:
TypeError: undefined is not a function.

Expected vs. Actual Results:

Expected: The function should execute without errors.

Actual: The error occurs, and the function doesn’t run.

Error Context:
The error happens when I call myFunction() in this snippet:

JavaScript (the issue arises in a larger project, but the simplified example below replicates it)

let myFunction = undefined;
myFunction(); // Throws "TypeError: undefined is not a function"

What I’ve Tried:

Checked if the function is properly defined before calling it.

Verified that there are no typos in the function name.

Confirmed the function is in scope (not blocked by conditional logic).

Browser: Chrome (latest version).

Question:
What are the common causes of this error, and how can I debug/fix it?

In React + TypeScript, when should a prop be prop?: Type vs prop: Type | undefined? [duplicate]

When designing TypeScript props for React components,
I’m sometimes unsure whether I should type props like:

prop?: Type

or

prop: Type | undefined

My understanding so far:

prop?: Type

The prop itself is optional — the component can be used without passing this prop.

If the prop is passed, it must be of the given Type.

prop: Type | undefined

The prop is required — it must be passed every time,

but the value itself can be undefined.

The confusion:

In some cases, a prop is critical for logic inside the component (I will always use it),
but at runtime, it might temporarily be undefined during early renders or initialization.

Questions:

When should I prefer prop?: Type vs prop: Type | undefined?

Is it acceptable to use ?: even if the value is temporarily undefined at first?

What is considered the cleanest or most “production-quality” way to handle this in modern React + TypeScript projects?

How do large real-world applications typically approach this?

Waiting for response in login function async/await

I have login page on my application.
That’s part of logging function:

this.loginService.doLogin(this.request).then(res => {
 this.storage.set("auth-key", res.token);
 this.authService.identity();
 if (this.authService.isAuthenticated()) 
     this.router.navigate(["expert-profile", this.authService.getCurrentUser().id], { queryParams: { lang: this.lang } });
     return;
 } else {
     this.storage.remove("auth-key");
     this.router.navigateByUrl("/login");
 }
}).catch(err => {
    this.storage.remove("auth-key");
  });

identity() {
   if (this.storage.get("auth-key")) {
     this.fetch().then(res => {
       this.userIdentity = {
         id: res.id,
         isAuthorized: res.isAuthorized
       };
       sessionStorage.setItem("userLoggedId", JSON.stringify(this.userIdentity.id));
       this.authenticated = true;
     }).catch(err => {
       this.storage.remove("auth-key");
       sessionStorage.removeItem("userLoggedId");
       this.authenticated = false;
   });


  public async fetch(): Promise<User> {
     const response = this.http.get<User>(environment.userDetailsUrl, { headers: new HttpHeaders({ "Authorization": "Bearer " + this.storage.get("auth-key") }) });
     return await firstValueFrom(response);

}

I have following problem. To log in I must press login button two times because the first time the response from the fetch function will probably not arrive in time (this.authenticated = false;).
If I click login second time, this.authenticated is true, and user have redirect to proper page
How to make

Sending emoji over email using surrogate pair in NodeJs

I’m trying to send an email with the emoji uD83DuDC49 in the body. This emoji has already been placed inside an AWS SES template. Sourcing the HTML string from SES using the following function:

getAndFillSESEmailTemplate: (templateName, templateData) => {
    return new Promise((resolve, reject) => {
      var params = {
        TemplateName: templateName
      };
      ses.getTemplate(params, (err, data) => {
          if(err){
            return reject(err);
          }
          var templateHTML = data.Template.HtmlPart;
          var templateDataKeys = Object.keys(templateData);
          templateDataKeys.forEach((key)=>{
            console.log(key);
            templateHTML = templateHTML.replaceAll('{{'+key+'}}', templateData[key])
          })
          return resolve(templateHTML);
      });
    });
  },

I’ve set the below as encoding type for the raw email data:

var htmlEntity = mimemessage.factory({
      contentType: "text/html;charset=utf-8",
      body: bodyData, //HTML data from AWS SES Template
    });

When i send the email out it does not display the emoji and instead displays the code uD83DuDC49. However when i copy the exact html into a variable like below the emoji is displayed correctly:

var copiedHTML = `**exact copy of what is being provided by AWS SES HtmlPart**`
var htmlEntity = mimemessage.factory({
      contentType: "text/html;charset=utf-8",
      body: copiedHTML, //Copy paste value from SES Template
    });

I’ve read up thats its related to how string variables are encoded in Javascript but i’m in need of some guidance. I cannot seem to find a solution that explains why the above happens.

Thanks.

How can I sync multiple chatbot conversations (tabs) per user with Firebase (HTML/JS only)

I am building a simple AI chatbot website using only HTML, CSS, and vanilla JavaScript (no frameworks). I’ve already set up Firebase Authentication and Firestore. Users can log in and see a chat interface with multiple tabs (for different conversations).

What I want:

When a user logs in, their existing conversations (tabs) should load from Firestore.
Each conversation should store its title and messages.
When a new conversation is created or updated (with new messages), it should be saved to Firestore under the current user’s UID.
Everything should be synced per user account.
I’m struggling to figure out the best way to structure the Firestore database and handle creating, loading, and updating conversations per user.

Has anyone done this with pure JS (no React/Vue)? What’s the best practice for structuring the Firestore collections and syncing the data correctly?

Thanks in advance!

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Rabbit AI Beta</title>
  <script defer src="https://cdn.tailwindcss.com"></script>
  <link rel="stylesheet" href="style.css" />
  <!-- Firebase SDK -->
  <script type="module">
    import { initializeApp } from "https://www.gstatic.com/firebasejs/10.8.0/firebase-app.js";
    import { getAuth, GoogleAuthProvider, signInWithPopup, signOut, onAuthStateChanged } from "https://www.gstatic.com/firebasejs/10.8.0/firebase-auth.js";
    import { getFirestore, doc, setDoc, getDoc, collection, addDoc, deleteDoc, onSnapshot, Timestamp } from "https://www.gstatic.com/firebasejs/10.8.0/firebase-firestore.js";
    import { firebaseConfig } from "./config.js";
    
    const app = initializeApp(firebaseConfig);
    const auth = getAuth(app);
    const db = getFirestore(app);
    const provider = new GoogleAuthProvider();

    // Array to store chat tabs
    let chatTabs = [];
    let currentTabIndex = 0;
    let unsubscribeFromTabs = null;
    let autoSaveInterval = null;

    // Function to save tabs to Firestore
    async function saveTabsToFirestore(userId) {
      if (!userId) return;
      try {
        const userDoc = doc(db, 'users', userId);
        // Ensure each tab has a unique ID and proper structure
        const tabsToSave = chatTabs.map(tab => ({
          id: tab.id || crypto.randomUUID(), // Generate unique ID if not exists
          title: tab.title || 'New Chat',
          messages: tab.messages || [],
          createdAt: tab.createdAt || Timestamp.now(),
          lastUpdated: Timestamp.now()
        }));
        
        await setDoc(userDoc, { 
          tabs: tabsToSave,
          lastUpdated: Timestamp.now()
        });
      } catch (error) {
        console.error('Error saving tabs:', error);
      }
    }

    // Function to start auto-save
    function startAutoSave(userId) {
      if (autoSaveInterval) {
        clearInterval(autoSaveInterval);
      }
      autoSaveInterval = setInterval(() => {
        if (auth.currentUser) {
          saveTabsToFirestore(userId);
        }
      }, 60000); // Save every minute
    }

    // Function to stop auto-save
    function stopAutoSave() {
      if (autoSaveInterval) {
        clearInterval(autoSaveInterval);
        autoSaveInterval = null;
      }
    }

    // Function to load tabs from Firestore
    async function loadTabsFromFirestore(userId) {
      if (!userId) return;
      
      if (unsubscribeFromTabs) {
        unsubscribeFromTabs();
      }

      try {
        const userDoc = doc(db, 'users', userId);
        
        // First, get the current state
        const docSnap = await getDoc(userDoc);
        if (docSnap.exists()) {
          const data = docSnap.data();
          chatTabs = data.tabs || [];
          updateChatList();
          if (chatTabs.length > 0) {
            loadChatMessages(currentTabIndex);
          }
        }

        // Start auto-save
        startAutoSave(userId);

        // Set up real-time listener
        unsubscribeFromTabs = onSnapshot(userDoc, (docSnap) => {
          if (docSnap.exists()) {
            const data = docSnap.data();
            const newTabs = data.tabs || [];
            
            if (JSON.stringify(chatTabs) !== JSON.stringify(newTabs)) {
              chatTabs = newTabs;
              updateChatList();
              if (chatTabs.length > 0) {
                loadChatMessages(currentTabIndex);
              }
            }
          }
        });
      } catch (error) {
        console.error('Error loading tabs:', error);
      }
    }

    // Function to clear all tabs
    function clearAllTabs() {
      chatTabs = [];
      currentTabIndex = 0;
      updateChatList();
      document.getElementById('chat').innerHTML = '';
      
      // Unsubscribe from real-time updates when clearing tabs
      if (unsubscribeFromTabs) {
        unsubscribeFromTabs();
        unsubscribeFromTabs = null;
      }
      
      // Stop auto-save
      stopAutoSave();
    }

    // Function to update the chat list UI
    function updateChatList() {
      const chatList = document.getElementById('chatList');
      chatList.innerHTML = '';
      
      if (!auth.currentUser) {
        // Show message when not logged in
        const message = document.createElement('div');
        message.className = 'text-center text-gray-500 p-4';
        message.textContent = 'Log in to see your chats';
        chatList.appendChild(message);
        return;
      }

      chatTabs.forEach((tab, index) => {
        const tabElement = document.createElement('div');
        tabElement.className = `flex items-center justify-between p-2 hover:bg-gray-100 rounded cursor-pointer ${index === currentTabIndex ? 'bg-gray-200' : ''}`;
        tabElement.innerHTML = `
          <span>${tab.title || 'New Chat'}</span>
          <button onclick="deleteTab(${index})" class="text-red-500 hover:text-red-700">×</button>
        `;
        tabElement.onclick = () => switchTab(index);
        chatList.appendChild(tabElement);
      });
    }

    // Function to load chat messages for a specific tab
    function loadChatMessages(tabIndex) {
      if (!auth.currentUser || !chatTabs[tabIndex]) return;
      
      const chatContainer = document.getElementById('chat');
      chatContainer.innerHTML = '';
      
      const messages = chatTabs[tabIndex].messages || [];
      messages.forEach(msg => {
        const messageElement = document.createElement('div');
        messageElement.className = `p-4 mb-2 rounded ${msg.role === 'user' ? 'bg-blue-100 ml-4' : 'bg-gray-100 mr-4'}`;
        messageElement.textContent = msg.content;
        chatContainer.appendChild(messageElement);
      });
      
      chatContainer.scrollTop = chatContainer.scrollHeight;
    }

    // Function to add a new message to the current tab
    async function addMessage(content, role) {
      if (!auth.currentUser || !chatTabs[currentTabIndex]) return;
      
      try {
        const message = {
          id: crypto.randomUUID(),
          content,
          role,
          timestamp: Timestamp.now()
        };
        
        if (!chatTabs[currentTabIndex].messages) {
          chatTabs[currentTabIndex].messages = [];
        }
        
        chatTabs[currentTabIndex].messages.push(message);
        await saveTabsToFirestore(auth.currentUser.uid);
      } catch (error) {
        console.error('Error adding message:', error);
      }
    }

    // Handle login button click
    document.getElementById('loginBtn').addEventListener('click', () => {
      const modal = document.getElementById('loginModal');
      modal.classList.remove('hidden');
    });

    // Handle close modal button
    document.getElementById('closeModal').addEventListener('click', () => {
      const modal = document.getElementById('loginModal');
      modal.classList.add('hidden');
    });

    // Handle Google login
    document.getElementById('googleLoginBtn').addEventListener('click', () => {
      signInWithPopup(auth, provider)
        .then((result) => {
          const modal = document.getElementById('loginModal');
          modal.classList.add('hidden');
          loadTabsFromFirestore(result.user.uid);
        })
        .catch((error) => {
          console.error('Error during Google sign-in:', error.message);
          alert('Error during sign-in: ' + error.message);
        });
    });

    // Handle logout
    document.getElementById('logoutBtn').addEventListener('click', () => {
      const user = auth.currentUser;
      if (user) {
        saveTabsToFirestore(user.uid).then(() => {
          signOut(auth).then(() => {
            updateAuthUI();
            clearAllTabs();
          });
        });
      } else {
        signOut(auth);
      }
    });

    // Update UI based on auth state
    function updateAuthUI() {
      const loginBtn = document.getElementById('loginBtn');
      const logoutBtn = document.getElementById('logoutBtn');
      const userDisplay = document.getElementById('userDisplay');

      if (auth.currentUser) {
        loginBtn.classList.add('hidden');
        logoutBtn.classList.remove('hidden');
        userDisplay.textContent = auth.currentUser.displayName || 'User';
        userDisplay.classList.remove('hidden');
      } else {
        loginBtn.classList.remove('hidden');
        logoutBtn.classList.add('hidden');
        userDisplay.classList.add('hidden');
      }
    }

    // Listen for auth state changes
    onAuthStateChanged(auth, (user) => {
      updateAuthUI();
      if (user) {
        console.log('User logged in:', user.uid);
        loadTabsFromFirestore(user.uid);
      } else {
        console.log('User logged out');
        clearAllTabs();
      }
    });

    // Expose functions to window for use in other scripts
    window.createNewChat = function() {
      if (!auth.currentUser) {
        const modal = document.getElementById('loginModal');
        modal.classList.remove('hidden');
        return;
      }
      
      try {
        const newTab = {
          id: crypto.randomUUID(),
          title: 'New Chat',
          messages: [],
          createdAt: Timestamp.now(),
          lastUpdated: Timestamp.now()
        };
        
        chatTabs.push(newTab);
        currentTabIndex = chatTabs.length - 1;
        updateChatList();
        loadChatMessages(currentTabIndex);
        saveTabsToFirestore(auth.currentUser.uid);
      } catch (error) {
        console.error('Error creating new chat:', error);
      }
    };

    window.deleteTab = function(index) {
      if (!auth.currentUser) return;
      
      try {
        chatTabs.splice(index, 1);
        if (currentTabIndex >= chatTabs.length) {
          currentTabIndex = Math.max(0, chatTabs.length - 1);
        }
        updateChatList();
        if (chatTabs.length > 0) {
          loadChatMessages(currentTabIndex);
        } else {
          document.getElementById('chat').innerHTML = '';
        }
        saveTabsToFirestore(auth.currentUser.uid);
        console.log('Tab deleted');
      } catch (error) {
        console.error('Error deleting tab:', error);
      }
    };

    window.switchTab = function(index) {
      if (!auth.currentUser) return;
      currentTabIndex = index;
      updateChatList();
      loadChatMessages(index);
    };

    // Handle sending messages
    window.sendMessage = async function() {
      if (!auth.currentUser) return;
      
      const input = document.getElementById('userInput');
      const message = input.value.trim();
      if (!message) return;
      
      // Add user message
      await addMessage(message, 'user');
      input.value = '';
      
      // Here you would typically add the AI response
      // For now, we'll just echo the message
      await addMessage(`AI: ${message}`, 'assistant');
    };
  </script>
  <script defer src="script.js"></script>
</head>
<body class="bg-white text-black h-screen flex transition-colors" id="body">
  <!-- Login Modal -->
  <div id="loginModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden">
    <div class="bg-white p-8 rounded-lg shadow-lg max-w-md w-full">
      <div class="flex justify-between items-center mb-6">
        <h2 class="text-2xl font-bold">Sign in to RabbitAI</h2>
        <button id="closeModal" class="text-gray-500 hover:text-gray-700">
          <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
          </svg>
        </button>
      </div>
      <button id="googleLoginBtn" class="w-full bg-white border border-gray-300 rounded-lg px-4 py-2 flex items-center justify-center gap-2 hover:bg-gray-50">
        <img src="https://www.gstatic.com/firebasejs/ui/2.0.0/images/auth/google.svg" alt="Google logo" width="18" height="18">
        Sign in with Google
      </button>
    </div>
  </div>

  <!-- Sidebar -->
  <div id="sidebar" class="w-64 bg-white border-r border-gray-200 flex flex-col p-4">
    <div class="flex justify-between items-center mb-6">
      <h2 class="text-lg font-bold">Tabs</h2>
      <button onclick="createNewChat()" class="bg-pink-500 hover:bg-pink-600 p-2 rounded text-sm text-white" style="color: #ffffff;">
        +
      </button>
    </div>
    <div id="chatList" class="flex-1 space-y-2 overflow-y-auto">
      <!-- Dynamisch geladen chats komen hier -->
    </div>
    <div class="mt-4 text-sm text-gray-400">
      <button onclick="openSettings()" class="hover:underline">Settings</button>
    </div>
  </div>

  <!-- Main Content -->
  <div class="flex flex-col flex-1 h-screen">
    <header class="text-center py-4 border-b border-gray-200 flex justify-between px-4 items-center">
      <div class="flex gap-2 items-center">
        <button onclick="toggleSidebar()" class="text-xl font-bold px-2 py-1">☰</button>
        <h1 class="text-xl font-bold">Rabbit AI</h1>
      </div>
      <div class="flex gap-2 items-center">
        <span id="userDisplay" class="hidden text-sm text-gray-600"></span>
        <button id="loginBtn" class="bg-gray-100 hover:bg-gray-200 text-gray-800 px-3 py-1 rounded text-sm">Guest</button>
        <button id="logoutBtn" class="hidden bg-gray-100 hover:bg-gray-200 text-gray-800 px-3 py-1 rounded text-sm">Log out</button>
        <button onclick="resetChat()" class="bg-pink-500 hover:bg-pink-600 text-white px-3 py-1 rounded text-sm">Reset</button>
      </div>
    </header>

    <main id="chat" class="flex-1 overflow-y-auto p-4 space-y-2"></main>

    <footer class="p-4 border-t border-gray-200">
      <div class="flex gap-2">
        <select id="modelSelect" class="px-3 py-2 rounded bg-gray-100 text-black outline-none border border-gray-300">
          <option value="mistralai/mistral-7b-instruct:free">Censored RabbitAI</option>
          <option value="cognitivecomputations/dolphin3.0-mistral-24b:free">Uncensored RabbitAI</option> 
        </select>
        <input id="userInput" type="text" placeholder="Aks a question privately..." class="flex-1 px-4 py-2 rounded bg-gray-100 text-black outline-none">
        <button onclick="sendMessage()" class="bg-pink-500 hover:bg-pink-600 text-white px-4 py-2 rounded">Send</button>
        <a href="#" class="flex items-center gap-1 font-semibold text-pink-500 hover:underline px-3 py-2 rounded"><span class="text-lg">✨</span>Upgrade to Pro</a>
      </div>
    </footer>
  </div>
</body>
</html>

Please note: when you click ‘run code snnippet’ you’ll get script errors, I don’t have these. I don’t have any errors. that makes it weird.

How can I pass data from multiple HTML tables to a controller using jQuery AJAX?

I’ve created a page with header fields and an HTML table. I’m using jQuery AJAX to send both the header and table data to the controller. Although the request reaches the controller, the action method receives null values.

I’ve tried setting the contentType to both 'application/x-www-form-urlencoded; charset=UTF-8' and 'application/json; charset=UTF-8', but in both cases the controller still receives null.

function addRow() {
  const row = document.createElement("tr");
  row.innerHTML = '<td><input type="text" class="itemNo"></td>' +
    '<td><input type="text" class="itemName"></td>' +
    '<td><input type="number" class="qty" onchange="calculateAmount(this)"></td>' +
    '<td> <input type="number" class="mrp" onchange="calculateAmount(this)"></td>' +
    '<td class="amount"> <label></label></td > ' +
    '<td><button onclick="removeRow(this)">-</button></td>';
  document.getElementById("invoiceTable").appendChild(row);
}

function removeRow(button) {
  button.closest("tr").remove();
}

function MakeSingleModel() {
  const SaleModel = {
    CustomerNo: $("#customerNo").val().trim(),
    CustomerName: $("#customerName").val().trim(),
  };

  const Detail = [];

  $("#invoiceTable tr").each(function() {
    const $row = $(this);
    const SaleList = {
      ItemNo: $row.find("input[name='itemNo']").val().trim(),
      ItemName: $row.find("input[name='itemName']").val().trim(),
      Qty: parseInt($row.find("input[name='qty']").val()) || 0,
      MRP: parseFloat($row.find("input[name='MRP']").val()) || 0,
      Amount: parseFloat($row.find("input[name='Amount']").text()) || 0
    };
    Detail.push(SaleList);
  });

  const alldata = {
    SaleModel: SaleModel,
    DetailList: Detail
  };

  SaveSale(alldata);
}

function SaveSale(data) {
  var data = {
    SaleData: data
  };
  
  $.ajax({
    type: "POST",
    url: "/Home/Create/",
    data: data,

    //contentType: "application/x-www-form-urlencoded; charset=UTF-8",
    contentType: "application/json; charset=UTF-8",
    dataType: "json",
    success: (response) => {
      alert(response.saveStatus === "Success" ? "Data successfully saved!" : "Data not saved.");
    },
    error: (jqXHR, textStatus, errorThrown) => {

      alert("Error saving data. See console for details.");
    }
  });
}

function multi(element) {
  const $row = $(element).closest("tr");
  const qty = parseInt($row.find(".qty").val()) || 0;
  const MRP = parseFloat($row.find(".mrp").val()) || 0;
  const sumAmount = qty * MRP;
  $row.find(".amount label").text(sumAmount.toFixed(2));
}
body {
  font-family: Arial, sans-serif;
  margin: 20px;
}

.container {
  width: 50%;
  margin: auto;
}

table {
  width: 100%;
  border-collapse: collapse;
}

th,
td {
  padding: 10px;
  border: 1px solid #ccc;
}

input {
  width: 100%;
  padding: 5px;
}

button {
  margin-top: 10px;
  padding: 5px 10px;
  cursor: pointer;
}

#invoiceTable td input {
  width: 150px;
}
<div class="">
  <h2>Sale Invoice</h2>

  <label>Customer No:</label>
  <input type="text" id="customerNo">

  <label>Customer Name:</label>
  <input type="text" id="customerName">
  
  <table>
    <thead>
      <tr>
        <th>Item No</th>
        <th>Item Name</th>
        <th>Qty</th>
        <th>MRP</th>
        <th>Amount</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody id="invoiceTable">
      <tr>
        <td><input type="text" name="itemNo" id="itemNo"></td>
        <td><input type="text" name="itemName" id="itemName"></td>
        <td><input type="number" onchange="multi(this)" name="qty" id="qty" class="qty"></td>
        <td><input type="number" onchange="multi(this)" name="MRP" id="MRP" class="mrp"></td>
        <td class="amount"><label name="Amount" id="Amount"></label></td>
        <td><button onclick="addRow()">+</button></td>
      </tr>
    </tbody>
  </table>
  <button onclick="MakeSingleModel()">Save</button>
</div>
[HttpPost]
public JsonResult Create(SaleModel SaleData)
{
  return Json(new { value = "", Status = "Success" });
}

How is JavaScript able to sort dates when it’s supplied as string?

Consider the following object:

var abc = [
   {"id":"a","date":"2025-05-01T03:02:19Z"}, 
   {"id":"b","date":"2025-05-01T03:15:02Z"}, 
   {"id":"c","date":"2025-04-30T20:49:41Z"}
];

If I apply ascending sort to it, it’s giving me correct result.

var def = abc.sort(function(a, b) {
                var x = a.date;
                var y = b.date;
                return x < y ? -1 : x > y ? 1 : 0;
            });

for(var i = 0; i < def.length; i++){
    gs.print(def[i].date);
}

Output:

*** Script: 2025-04-30T20:49:41Z
*** Script: 2025-05-01T03:02:19Z
*** Script: 2025-05-01T03:15:02Z

How are strings getting sorted correctly?

“How to Properly Dispose Tensors in face-api.js + tfjs-node to Prevent Memory Leak?”

I’m using face-api.js (specifically the @vladmandic/face-api version) for the first time in a Node.js server environment, and while face detection and comparison are working, I’m running into a serious memory management issue.

Even though I try to manually dispose of tensors, memory usage keeps increasing over time on the server. I suspect some tensors are not being released correctly, but I can’t pinpoint where or why. I’ve wrapped tensor creation in try...finally blocks and even log memory using tf.memory(), but the number of active tensors doesn’t go down as expected.

// face-api/src/server.js
const express = require('express');
const multer = require('multer');
const tf = require('@tensorflow/tfjs-node');
const faceapi = require('@vladmandic/face-api');
const { Canvas, Image, ImageData } = require('canvas');
const path = require('path');
const { logger } = require('./logger');

const app = express();
const upload = multer({
  limits: {
    fileSize: 10 * 1024 * 1024,
    fieldSize: 25 * 1024 * 1024
  }
});
const PORT = 3002;

class FaceApiService {
  constructor() {
    this.modelPath = path.join(__dirname, '../models');
    this.isModelLoaded = false;
    this.initializeFaceApi();
  }

  async initializeFaceApi() {
    if (this.isModelLoaded) return;

    faceapi.env.monkeyPatch({ Canvas, Image, ImageData });

    try {
      await Promise.all([
        faceapi.nets.faceRecognitionNet.loadFromDisk(this.modelPath),
        faceapi.nets.faceLandmark68Net.loadFromDisk(this.modelPath),
        faceapi.nets.ssdMobilenetv1.loadFromDisk(this.modelPath)
      ]);

      this.isModelLoaded = true;
      console.log("load model success")
      logger.info('Face recognition models loaded successfully');
    } catch (error) {
      logger.error('Error loading face recognition models: ' + error);
      throw new Error("Error initializing face recognition system");
    }
  }

  disposeTensor(tensor) {
    if (tensor) {
      if (Array.isArray(tensor)) {
        tensor.forEach(t => this.disposeTensor(t));
      } else if (tensor.dispose) {
        try {
          tensor.dispose();
        } catch (err) {
          logger.warn('Error disposing tensor: ' + err);
        }
      }
    }
  }

  async verifyFace(uploadedImage, referenceImages) {
    let mem = tf.memory();
    console.log(`Tensor count: ${mem.numTensors}, Bytes: ${mem.numBytes}`);
    let inputTensor = null;
    const referenceDescriptors = [];
    try {
      console.log("uploadedImage size: ", uploadedImage.length / 1024, "KB");
      inputTensor = tf.node.decodeImage(uploadedImage);
      console.log("decoded imgae uploadedImage success")
      const detection = await faceapi
        .detectSingleFace(inputTensor)
        .withFaceLandmarks()
        .withFaceDescriptor();
      console.log("detection imgae uploadedImage success")

      if (!detection) {
        throw new Error("No face detected in the uploaded photo");
      }

      for (const refImage of referenceImages) {
        let refTensor = null;
        try {
          console.log("referenceImage size: ", refImage.length / 1024, "KB");
          refTensor = tf.node.decodeImage(refImage);
          console.log("decoded imgae refTensor success")
          const refDetection = await faceapi
            .detectSingleFace(refTensor)
            .withFaceLandmarks()
            .withFaceDescriptor();
          console.log("detection imgae refTensor success")

          if (refDetection) {
            referenceDescriptors.push(refDetection.descriptor);
          }
        } catch (refErr) {
          logger.warn('Error processing reference image: ' + refErr);
        } finally {
          this.disposeTensor(refTensor);
        }
      }

      if (referenceDescriptors.length === 0) {
        throw new Error("No valid reference photos available for comparison");
      }

      const faceMatcher = new faceapi.FaceMatcher(
        [new faceapi.LabeledFaceDescriptors('user', referenceDescriptors)],
        0.6
      );
      console.log("faceMatcher success")

      const match = faceMatcher.findBestMatch(detection.descriptor);
      console.log("match success")

      return {
        verified: match.label !== 'unknown',
        confidence: 1 - match.distance
      };

    } catch (err) {
      logger.error('Error in face verification: ' + err);
      throw err;
    } finally {
      console.log("dispose tensor")
      this.disposeTensor(inputTensor);
      // Dispose semua descriptor tensor reference
      for (const desc of referenceDescriptors) {
        this.disposeTensor(desc); // penting!
      }

      console.log("dispose success");
      let mem = tf.memory();
      console.log(`Tensor count: ${mem.numTensors}, Bytes: ${mem.numBytes}`);
    }
  }
}

const faceApiService = new FaceApiService();

app.use((req, res, next) => {
    const waktuAkses = new Date().toISOString();
    logger.info(`${req.method} url:: ${req.url} - accessed at ${waktuAkses}`);
    next();
});

app.get('/', (req, res) => {
  res.json({ status: true });
});

app.post('/verify', upload.single('image'), async (req, res) => {
  try {
    if (!req.file || !req.body.referenceImages) {
      return res.status(400).json({ error: 'Missing required files' });
    }

    const referenceImages = JSON.parse(req.body.referenceImages);
    const referenceBuffers = referenceImages.map(base64 =>
      Buffer.from(base64, 'base64')
    );

    const result = await faceApiService.verifyFace(
      req.file.buffer,
      referenceBuffers
    );

    res.json(result);
  } catch (error) {
    logger.error('Verification error: ' + error);
    res.status(500).json({
      error: error instanceof Error ? error.message : 'Internal server error'
    });
  }
});

app.listen(PORT, '0.0.0.0', () => {
  logger.info(`Face API service running on http://localhost:${PORT}`);
});

module.exports = app;

Receiving 0 ETH after BTC swap using Chainflip — Broadcast fee exactly the same as the amount before broadcast fee

I’m building a cross-chain swap dApp using Unisat Wallet and Chainflip. Users can swap BTC for WUSDT (via ETH as intermediary), and I’m integrating Chainflip’s API to handle the actual swap.

However, I’ve run into a critical issue during testing. When I initiate a BTC -> ETH swap, Chainflip responds with swap metadata like this (trimmed for clarity):

{
  "depositAmount": "100000",
  "intermediateAmount": "42516508",
  "egressAmount": "2797855777158",
  "estimatedPrice": "5.76474664160869368917",
  "includedFees": [
    {
      "type": "INGRESS", "amount": "330", "asset": "BTC"
    },
    {
      "type": "NETWORK", "amount": "42559", "asset": "USDC"
    },
    {
      "type": "EGRESS", "amount": "5742925121914227", "asset": "ETH"
    }
  ]
}

This results in Chainflip depositing approximately 0.00649142 ETH to the destination address. The problem is that Chainflip also deducts a broadcast fee of 0.00649142 ETH, which is exactly the amount they sent me.

The result is that I’m left with 0 ETH in the wallet, making it impossible to use for gas or forward it elsewhere.

Screenshot of the above mentioned issue

Convert nested array to multiple flat arrays

I don’t found here a solution for my problem. Because of this, here my issue:
I have an array of some parameters (like a YAML config file) and this need to be written to database finaly with primary ids and so on.

For example this is a part of my array:

$settings = [
'basic' => [                       // first level category
    'installation_type' => [       // setting parameter with parameter attributes
        'type' => '["single","cluster"]',
        'description' => 'bla blah',
        'readonly' => false,
        'hidden' => false,
        'trigger' => null,
        'default' => 'single'
    ],
    'db_master_host' => [
        'type' => 'ip',
        'description' => 'Database hostname or IP',
        'default' => 'localhost'
    ],
    'db_master_user' => [
        'type' => 'text',
        'description' => 'Database username',
        'default' => 'test'
    ],
    'db_master_pwd' => [
        'type' => 'secret',
        'description' => 'Database user password',
    ],
    'db_master_db' => [
        'type' => 'text',
        'description' => 'Database name',
        'default' => 'test'
    ]
],
'provisioning' => [         // first level category
    'snom' => [             // second level category
        'snom_prov_enabled' => [
            'type' => 'switch',
            'default' => false
        ],
        'snom_m3' => [
            'snom_m3_accounts' => [
                'type' => 'number',
                'description' => 'bla blah',
                'default' => '0'
            ]
        ],
        'snom_dect' => [
            'snom_dect_enabled' => [
                'type' => 'switch',
                'description' => 'bla blah',
                'default' => false
            ]
        ]
    ],
    'yealink' => [
        'yealink_prov_enabled' => [
            'type' => 'switch',
            'default' => false
        ]
    ]
],

];

As result I need some arrays like images of database tables (category, setting, value) with self-generated IDs:

$category["basic"] = [id: 1, parent: 0, name: "basic", order: 1]
$setting["installation_type"] = [id: 1, catId: 1, name: "installation_type", type: '["single","cluster"]', desc: 'asd', order: 1]
$value["installation_type"] = [id: 1, setId: 1, default: 'single']
$setting["db_master_host"] = [id: 2, catId: 1, name: "db_master_host", type: 'ip', desc: 'asd', order: 2]
$value["db_master_host"] = [id: 2, setId: 2, name: "db_master_host", default: 'localhost']
...
$category["provisioning"] = [id: 2, parent: 0, name: "provisioning", order: 2]
$category["snom"] = [id: 3, parent: 2, name: "snom", order: 3]
...

I hope my problem is understandable here and anyone could help me.

How to submit radio button attendance status for multiple students in PHP?

I’m working on a PHP project where I need to mark student attendance. I’ve already fetched the students from the database based on their class and section, and displayed them in a table. Each row has a student’s name and two radio buttons — one for Present and one for Absent.

My main challenge is:
How can I structure the radio button inputs and handle the form submission in PHP to store each student’s attendance status in the database?

<tr>
    <td class="text-center">
        <?php echo($no++);?>
    </td>
    <td class="text-center">
        <?php echo($studentId); ?>
    </td>
    <td class="text-center">
        <?php echo($studentName); ?>
    </td>
    <td class="text-center">
        <?php echo($fullClassName); ?>
    </td>
    <td class="text-center">
        <?php echo($attType); ?>
    </td>
    <td class="text-center">
        <label for="">Pre</label>
        <input type="radio" value="">
        <label for="">abs</label>
        <input type="radio" value="">
    </td>
</tr>

What I want to achieve:
When the form is submitted, loop through the attendance input in PHP.

Insert the attendance into a database table with fields like:

student_id

teacher_id

status (present or absent)

date

Exclude variable data if not found

How do I write my controller code below so that if $find is not present in Other OE Referances (the Data in the table is a string), then exclude?

I get that I potentially need to run Other OE Referances through a loop to separate them, and then check, but I also have a feeling I am overthinking.

Controller Snippet:

$find = 'G060162A2';

$letsFind = DB::table('parts')
            ->where('OE Number', '=', $find)
            ->orWhere('Other OE Referances', '=', $find)
            ->get();

Database:

object(stdClass)#584 (4) {
  ["ID"]=>
  int(23)
  ["internal ID"]=>
  string(6) "160980"
  ["OE Number"]=>
  string(9) "G060162A2"
  ["Other OE Referances"]=>
  string(37) "83222152426 ,83222289720, 83222305397"
}

im getting this error when i run this comand: php artisan migrate. Answer below in the link [duplicate]

SQLSTATE[HY000]: General error: 1005 Can’t create table madhhab.issues (errno: 150 “Foreign key constraint is incorrectly formed”) (Connection: mysql, SQL: alter table issues add constraint issues_subchapter_id_foreign foreign key (subchapter_id) references subchapters (id) on delete cascade)

i droped the table from database then run the commands php artisan migrate:rollback
php artisan migrate:fresh , php artisan migrate:refresh

enter code here

All these and i dont know how i can fix it
i tried some of the answers form stakoverflow but didnt work

im expecting just to migrate the tables and start the work im stuck in this error for hoursss

// Your code goes here
public function up() {
    Schema::create('issues', function (Blueprint $table) {
        $table->id();
        $table->text('title_ar');
        $table->text('title_sq');
        $table->timestamps();
    });
}

   public function up(): void
    {
        Schema::create('subchapters', function (Blueprint $table) {
            $table->id();
            $table->foreignId('chapter_id')->constrained('chapters')->onDelete('cascade');
            $table->string('title_ar');
            $table->string('title_sq');
            $table->integer('display_order');
            $table->timestamps();
        });

    }

Answer:
link