(HTML/JS) Button to create report based on JSON response to Database doesn’t work

Please, I’m going insane. I am currently doing a Database project with PostGreSQL using Python Flask for the backend and HTML/CSS/Javascript for the frontend. But on one of the pages where it’s supposed to have two button to create reports, one of them doesn’t work, and it gives the following error message in “Inspect Element” when I click it:

Uncaught (in promise) TypeError: Cannot read properties of null (reading ‘value’)
at fetchProdutoVendidoReport (script.js:50:61)
at HTMLButtonElement.onclick

And whenever I try to fix this, like giving “id”s to the HTML form, the other button/request in the same page fails, and both of them give 500: Internal Server Error.

Can anyone help me? This is the body of the HTML of the aforementioned page (I am Brazilian, so many of the things are in Portuguese, but I hope it isn’t too hard to decipher the problem):

<body>

    <div id="header"></div>
    <script src="/frontend/components/header/header.js"></script>

    <h1>Gerar Relatórios</h1>

    <!-- Formulário para Relatório de Pedido Cliente -->
    <h2>Relatório de Pedido Cliente</h2>
    <form id="pedidoClienteForm">
        <label>Categoria: <input type="text" id="categoria" name="categoria"></label><br>
        <label>Data Mínima: <input type="date" id="startDate" name="data_min"></label><br>
        <label>Data Máxima: <input type="date" id="endDate" name="data_max"></label><br>
        <label>Fabricante: <input type="text" id="marca" name="fabricante"></label><br>
        <label>Método de Pagamento: <input type="text" id="metodoPagamento" name="metodo"></label><br>
        <label>Preço Mínimo: <input type="number" id="precoMin" name="preco_min"></label><br>
        <label>Preço Máximo: <input type="number" id="precoMax" name="preco_max"></label><br>
        <button type="button" onclick="fetchPedidoClienteReport()">Gerar Relatório de Pedido Cliente</button>
    </form>
    <div id="pedidoClienteResultado"></div>

    <h2>Resultados</h2>
    <table id="TabelaPedidoCliente">
        <thead>
            <tr>
                <th>Produto</th>
                <th>Categoria</th>
                <th>Marca</th>
                <th>Total Vendido</th>
                <th>Receita Total</th>
                <th>Método de Pagamento</th>
                <th>Data de Venda</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>

    <!-- Formulário para Relatório de Produto Vendido -->
    <h2>Relatório de Produto Vendido</h2>
    <form id="produtoVendidoForm">
        <label>Data Mínima: <input type="date" name="data_min"></label><br>
        <label>Data Máxima: <input type="date" name="data_max"></label><br>
        <label>Preço Mínimo: <input type="number" name="preco_min"></label><br>
        <label>Preço Máximo: <input type="number" name="preco_max"></label><br>
        <button type="button" onclick="fetchProdutoVendidoReport()">Gerar Relatório de Produto Vendido</button>
    </form>
    <div id="produtoVendidoResultado"></div>

    <h2>Resultados</h2>
    <table id="TabelaProdutoVendido">
        <thead>
            <tr>
                <th>Produto</th>
                <th>Faixa de Preço</th>
                <th>Total Vendido</th>
                <th>Receita Total</th>
                <th>Método de Pagamento</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>

    <script src="/frontend/pages/relatorios/script.js"></script>
</body>

And this is the JS:

async function fetchPedidoClienteReport() {
        const startDate = document.getElementById('startDate').value;
        const endDate = document.getElementById('endDate').value;
        const categoria = document.getElementById('categoria').value;
        const marca = document.getElementById('marca').value;
        const precoMin = document.getElementById('precoMin').value;
        const precoMax = document.getElementById('precoMax').value;
        const metodoPagamento = document.getElementById('metodoPagamento').value;
        
        const url = `http://127.0.0.1:8000/relatorio/pedido_cliente?categoria=${categoria}&data_min=${startDate}&data_max=${endDate}&fabricante=${marca}&metodo=${metodoPagamento}&preco_min=${precoMin}&preco_max=${precoMax}`;
            try {
                // Envia a requisição para o backend
                const response = await fetch(url, {
                    method: 'GET'
                });
                
                // Converte a resposta para JSON
                const data = await response.json();
                
                // Atualiza a tabela com os dados recebidos
                    const tbody = document.getElementById('TabelaPedidoCliente').getElementsByTagName('tbody')[0];
        
                    // Limpa a tabela antes de preencher com os novos dados
                    tbody.innerHTML = '';
    
                    function formataData(dateString) {
                        const date = new Date(dateString);
                        return date.toLocaleDateString('pt-BR'); // Formato 'DD/MM/YYYY'
                    }
    
                    // Preenche a tabela com os dados do relatório
                    data.forEach(item => {
                        const row = tbody.insertRow();
                        
                    row.insertCell(0).textContent = item.nome;        // nome do produto
                    row.insertCell(1).textContent = item.categoria;      // categoria do produto
                    row.insertCell(2).textContent = item.fabricante;     // fabricante do produto
                    row.insertCell(3).textContent = item.quantidade;  // total vendido
                    row.insertCell(4).textContent = item.total_venda;  // receita total
                    row.insertCell(5).textContent = item.metodo;         // método de pagamento
                    row.insertCell(6).textContent = formataData(item.data);     // data da venda
                    })
            } catch (error) {
                console.error('Erro ao gerar o relatório:', error);
            }
    }
    
    // Função para buscar o Relatório de Produto Vendido
    async function fetchProdutoVendidoReport() {
        const DataComeco = document.getElementById('DataComeco').value;
        const DataFinal = document.getElementById('DataFinal').value;
        const Preco_Min = document.getElementById('preco_Min').value;
        const Preco_Max = document.getElementById('preco_Max').value;
        
        const url = `http://127.0.0.1:8000/relatorio/produto_vendido?data_min=${DataComeco}&data_max=${DataFinal}&preco_min=${Preco_Min}&preco_max=${Preco_Max}`;
            try {
                // Envia a requisição para o backend
                const response = await fetch(url, {
                    method: 'GET'
                });
                
                // Converte a resposta para JSON
                const data = await response.json();
                
                // Atualiza a tabela com os dados recebidos
                    const tbody = document.getElementById('TabelaProdutoVendido').getElementsByTagName('tbody')[0];
    
                    // Limpa a tabela antes de preencher com os novos dados
                    tbody.innerHTML = '';
    
                    // Preenche a tabela com os dados do relatório
                    data.forEach(item => {
                        const row = tbody.insertRow();
                        
                    row.insertCell(0).textContent = item.nome;        // nome do produto
                    row.insertCell(1).textContent = item.faixa_preco;      // categoria do produto
                    row.insertCell(2).textContent = item.total_vendido;     // fabricante do produto
                    row.insertCell(3).textContent = item.receita_total;  // total vendido
                    row.insertCell(4).textContent = item.metodo;         // método de pagamento
                    })
            } catch (error) {
                console.error('Erro ao gerar o relatório:', error);
            }
    }

Websocket errors in a Vite and Vue Application

I have an app with an express-server running on the backend, I have tried hosting the backend on ngrok as well but I still get a websocket error: The post methods are working fine and it does return the desired result but websocket connection does not do the same:

My Backend is running on port 3001:

Frontend on default Vite 5173 port:

This is the frontend component trying to communicate with the backend:

<template>
  <div>
    <h3>Sign In</h3>
    <div v-if="loading">
      <Loading />
    </div>
    <div v-else>
      <div v-if="QRData">
        <QRCode :value="QRData" />
        <p>Please scan the QR code with your Verus Mobile app.</p>
      </div>
      <div v-else>
        <button @click="handleLogin">Login with your ID</button>
      </div>
      <p>
        Get <a href="#">Verus Wallet</a>
      </p>
    </div>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue';
import { login } from '../scripts/login';  
import Loading from './Loading.vue';
import QRCode from 'qrcode-vue'

const challengeID = ref(null);
const showLoginQR = ref(false);
const QRData = ref('');
const loading = ref(false);
const handleLogin = async () => {
  try {
    loading.value = true;
    const reply = await login();

  console.log('Login Response:', reply);

    if (reply?.success) {
      showLoginQR.value = true;
      QRData.value = reply.data.deepLink;
      challengeID.value = reply.data.challengeID;  // This will be set when login is successful
      loading.value = false;
    } else {
      // Handle error here
      loading.value = false;
    }
  } catch (error) {
    console.error(error);
    loading.value = false;
  }
};

// Watch for changes in challengeID and initiate WebSocket connection when it is set
watch(challengeID, (newChallengeID) => {
  if (newChallengeID) {
    const socket = new WebSocket(`${import.meta.env.VITE_WS_SERVER}/awaitlogin/${newChallengeID}`);
    socket.onopen = () => {
      console.log("WebSocket connection established");
    };

    socket.onmessage = (event) => {
      const receivedMessage = JSON.parse(event.data);
      console.log("Received message:", receivedMessage);
      localStorage.setItem("token", JSON.stringify(receivedMessage.JWT));
      localStorage.setItem("iaddress", receivedMessage.iaddress);
      localStorage.setItem("name", receivedMessage.name);
      window.location.assign("/loggedin");
    };

    socket.onerror = (error) => {
      console.error("WebSocket Error:", error);
    };

    socket.onclose = () => {
      console.log("WebSocket connection closed");
    };

    return () => {
      socket.close();
    };
  }
});
</script>

The backend script that is interacting with the websockets is the following:

import expressWs from 'express-ws';
import cors from 'cors';

const app = express();
expressWs(app);


const registeredChallengeIDs = new Set();
const clients = new Map();

app.ws('/awaitlogin/:challengeid', (ws, req) => {
  const { challengeid } = req.params;
  console.log(`WebSocket challengeid connected ${challengeid}`);

  clients.set(ws, challengeid);

  ws.on('message', (data) => {
    console.log(`Received message: ${data}`);
  });

  ws.on('close', () => {
    clients.delete(ws);
    console.log('WebSocket client disconnected');
  });
});

export { registeredChallengeIDs, clients, app };

I have got 3 files in the backend:

A login.js this handles the login by running some third party library functions
A websocket.js this handles the websocket as above
An index.js which imports both and runs

I suppose the error might be from the front-end cause backend console displays nothing and I get the errors in the browser console

Angular 18 Application ‘NOT FOUND’ error when deploying to Heroku

I recently upgraded my Angular/Ionic project to Angular 18 and I know that modified the angular.json and probably the project structure a bit.

Now my application returns a NOT FOUND and Heroku gives the error:
2024-11-14T20:35:46.715083+00:00 app[web.1]: Error: ENOENT: no such file or directory, stat '/app/dist/church_website_frontend/index.html'

Again, I never touched anything except upgrading. I didn’t mess with my server.js file either.

server.js file:

const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(__dirname + '/dist/church_website_frontend'));
app.get('/*', function(req,res) {
res.sendFile(path.join(__dirname+
'/dist/church_website_frontend/index.html'));});
app.listen(process.env.PORT || 8080);

manifest.webmanifest:

{
  "name": "The Father's House Ministry",
  "short_name": "The Father's House Ministry",
  "theme_color": "#ffffff",
  "background_color": "#ffffff",
  "display": "standalone",
  "scope": "./",
  "start_url": "./",
  "icons": [
    {
      "src": "assets/icons/app_home-72x72.png",
      "sizes": "72x72",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "assets/icons/app_home-96x96.png",
      "sizes": "96x96",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "assets/icons/app_home-128x128.png",
      "sizes": "128x128",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "assets/icons/app_home-144x144.png",
      "sizes": "144x144",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "assets/icons/app_home-152x152.png",
      "sizes": "152x152",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "assets/icons/app_home-192x192.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "assets/icons/app_home-384x384.png",
      "sizes": "384x384",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "assets/icons/app_home-512x512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "maskable any"
    }
  ]
}

package.json

"scripts": {
    "ng": "ng",
    "start": "node server.js",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "heroku-postbuild": "ng build --configuration production"
  },

angular.json

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "app": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "prefix": "app",
      "schematics": {},
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:application",
          "options": {
            "outputPath": {
              "base": "dist/church_website_frontend"
            },
            "index": "src/index.html",
            "polyfills": ["zone.js"],
            "tsConfig": "tsconfig.app.json",
            "assets": [
              {
                "glob": "**/*",
                "input": "src/assets",
                "output": "assets"
              },
              {
                "glob": "**/*.svg",
                "input": "node_modules/ionicons/dist/ionicons/svg",
                "output": "./svg"
              },
              "src/manifest.webmanifest"
            ],
            "styles": [
              "./node_modules/@angular/material/prebuilt-themes/pink-bluegrey.css",
              "src/theme/variables.scss",
              "src/global.scss"
            ],
            "scripts": [],
            "aot": false,
            "extractLicenses": false,
            "sourceMap": true,
            "optimization": true,
            "namedChunks": true,
            "serviceWorker": "ngsw-config.json",
            "browser": "src/main.ts"
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                }
              ]
            },
            "ci": {
              "progress": false
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "buildTarget": "app:build"
          },
          "configurations": {
            "production": {
              "buildTarget": "app:build:production"
            },
            "ci": {
              "progress": false
            }
          }
        },

I checked my dist folder because I assume that was the issue and I noticed my index.html is not where it’s trying to look for it. enter image description here

I tried changing my server.js sendfile method to be: res.sendFile(path.join(__dirname+ '/dist/church_website_frontend/browser/index.html'));});

because my dist has a browser folder and the index.html is in there, but that also didn’t work. Heroku shows everything is semi-good – showing 200s and 304s?:

2024-11-14T20:57:14.728965+00:00 heroku[router]: at=info method=GET path="/chunk-HV4COAZO.js" host=tfh-website.herokuapp.com request_id=0776ef0b-a41c-4c46-93ca-d2dfe7258363 fwd="98.214.25.29" dyno=web.1 connect=0ms service=1ms status=200 bytes=99574 protocol=https
2024-11-14T20:57:14.746753+00:00 heroku[router]: at=info method=GET path="/polyfills-SCHOHYNV.js" host=tfh-website.herokuapp.com request_id=c0c7f576-702a-419a-9c2a-493dba029d69 fwd="98.214.25.29" dyno=web.1 connect=1ms service=1ms status=200 bytes=99574 protocol=https
2024-11-14T20:57:14.749251+00:00 heroku[router]: at=info method=GET path="/main-UX3TQ3VX.js" host=tfh-website.herokuapp.com request_id=cf071216-fd67-4ee9-9dd2-48fa6fe4fd67 fwd="98.214.25.29" dyno=web.1 connect=0ms service=2ms status=200 bytes=99574 protocol=https
2024-11-14T20:57:14.826664+00:00 heroku[router]: at=info method=GET path="/assets/icon/church-icon-trimmed.webp" host=tfh-website.herokuapp.com request_id=ebf0a91c-8657-4236-9e04-9c94dee03fe4 fwd="98.214.25.29" dyno=web.1 connect=3ms service=2ms status=200 bytes=99574 protocol=https
2024-11-14T20:57:14.861093+00:00 heroku[router]: at=info method=GET path="/assets/icon/church-icon-trimmed.webp" host=tfh-website.herokuapp.com request_id=458950a5-aa14-4ee0-be98-abdb922b73df fwd="98.214.25.29" dyno=web.1 connect=0ms service=1ms status=206 bytes=342 protocol=https
2024-11-14T20:57:14.896648+00:00 heroku[router]: at=info method=GET path="/assets/icon/church-icon-trimmed.webp" host=tfh-website.herokuapp.com request_id=7fa6ee47-1a1f-44b0-bdba-f9e2813a3b91 fwd="98.214.25.29" dyno=web.1 connect=0ms service=1ms status=206 bytes=85439 protocol=https
2024-11-14T20:57:14.905954+00:00 heroku[router]: at=info method=GET path="/assets/icon/church-icon-trimmed.webp" host=tfh-website.herokuapp.com request_id=2bfd4069-0504-4bad-9a54-ae0e1ae81a08 fwd="98.214.25.29" dyno=web.1 connect=0ms service=1ms status=206 bytes=342 protocol=https
2024-11-14T20:57:14.946727+00:00 heroku[router]: at=info method=GET path="/assets/icon/church-icon-trimmed.webp" host=tfh-website.herokuapp.com request_id=fd87cd87-aaa5-4f3b-9614-7c9098164e3b fwd="98.214.25.29" dyno=web.1 connect=0ms service=2ms status=206 bytes=85439 protocol=https
2024-11-14T20:57:14.990030+00:00 heroku[router]: at=info method=GET path="/assets/icon/church-icon-trimmed.webp" host=tfh-website.herokuapp.com request_id=ba1b05b2-170a-4d07-bbfd-9deea0d021cb fwd="98.214.25.29" dyno=web.1 connect=0ms service=1ms status=304 bytes=239 protocol=https
2024-11-14T20:57:15.045759+00:00 heroku[router]: at=info method=GET path="/manifest.webmanifest" host=tfh-website.herokuapp.com request_id=8d41f52a-e3e0-4a73-a301-e1b842133210 fwd="98.214.25.29" dyno=web.1 connect=0ms service=2ms status=200 bytes=99574 protocol=https
2024-11-14T21:01:31.394748+00:00 heroku[router]: at=info method=GET path="/chunk-HV4COAZO.js" host=tfh-website.herokuapp.com request_id=433fb0d1-a420-479d-b955-66b6c2268087 fwd="98.214.25.29" dyno=web.1 connect=0ms service=1ms status=304 bytes=239 protocol=https
2024-11-14T21:01:31.376672+00:00 heroku[router]: at=info method=GET path="/chunk-QM5HIALM.js" host=tfh-website.herokuapp.com request_id=23c70e90-e6ff-423d-8fce-f9591ac72e25 fwd="98.214.25.29" dyno=web.1 connect=0ms service=1ms status=304 bytes=239 protocol=https

BUT the application actually fails in the browser with:

Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.

&

manifest.webmanifest:1 Manifest: Line: 1, column: 1, Syntax error.

Any Help would be greatly appreciated?

getElementById() not working properly with Firefox

I have code that enables a user to click on a button to copy an HTML table and paste it into Excel/Notepad/etc. When the user attempts to copy/paste the table using Firefox, the table headers are not included. If the user uses Chrome, or Edge, the table headers are included. The issue also seems to appear if the user is using Citrix to access the network.

I’ve outputted the contents of the getElementById() to the console log and the output is different between Firefox and Chrome/Edge. For Chrome/Edge I can clearly see the section when I expand the section, but the output in Firefox is completely different when I expand the section.

The PHP code that calls the JavaScript code is:

echo "<button onclick="copyElementToClipboard('" . str_replace("~","_",$table_id) ."')">Copy table to clipboard</button>";

The JavaScript code is:

function copyElementToClipboard(objName) {
        el = document.getElementById(objName);
        console.log(el);
        var body = document.body, range, sel;
        if (document.createRange && window.getSelection) {
            range = document.createRange();
            sel = window.getSelection();
            sel.removeAllRanges();
            try {
                range.selectNodeContents(el);
                sel.addRange(range);
            } catch (e) {
                range.selectNode(el);
                sel.addRange(range);
            }
        } else if (body.createTextRange) {
            range = body.createTextRange();
            range.moveToElementText(el);
            range.select();
        }
        var succeed;
         try {
             succeed = document.execCommand("copy");
            // alert("Table copied to clipboard.");
         } catch(e) {
             succeed = false;
             alert("Copy failed.");
         }
         sel.removeAllRanges();//Clear selection
    }

Unable to upload excel file (from memory buffer) to GCS bucket

Just want to be able to upload a buffer (data is a Buffer) as a file in GCS bucket.

await storage
    .bucket("docflow-files")
    .file(`input_files/${filename}`)
    .save(data);

I have tried adding options with the save function to upload the excel file (even though I should be able to upload any type of file without specifying the content type):

  • .save(data, {resumable: false})
  • .save(data, {resumable: false, contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"})

But I’m getting this error when the client library tries to POST a file:

<p><b>400.</b> <ins>That’s an error.</ins>
  <p>Your client has issued a malformed or illegal request.  <ins>That’s all we know.</ins>

The same kind of code works if I use a PDF file and content type:

await storage
    .bucket("docflow-files")
    .file(`input_files/${filename}`)
    .save(data, {resumable: false, contentType: "application/pdf"});

Cannot find module ‘react’ Error When Running Expo Project in Web Browser

I’m working on my first React Native project using React Native with Expo, and I’m encountering a frustrating issue. The project runs fine on the Expo Go app on my Android device, but when I try to view it in a web browser on my Windows laptop, I keep getting the following error:

Metro error: Cannot find module 'react'
Require stack:
- /C:%5CUsers%5CMuhammed%20Tauqeer%20Ali%5CSocialSphere%5Cnode_modules%5Cexpo-router%5Cnode%5Crender.js.bundle?platform=web&dev=true&hot=false&transform.engine=hermes&transform.routerRoot=app&resolver.environment=node&transform.environment=node&unstable_transformProfile=hermes-stable
- C:UsersMuhammed Tauqeer AliSocialSpherenode_modules@expoclibuildsrcstartservergetStaticRenderFunctions.js
- C:UsersMuhammed Tauqeer AliSocialSpherenode_modules@expoclibuildsrcstartservermetrometroErrorInterface.js
- C:UsersMuhammed Tauqeer AliSocialSpherenode_modules@expoclibuildsrcstartservermetrocreateServerComponentsMiddleware.js
- C:UsersMuhammed Tauqeer AliSocialSpherenode_modules@expoclibuildsrcstartservermetroMetroBundlerDevServer.js
- C:UsersMuhammed Tauqeer AliSocialSpherenode_modules@expoclibuildsrcstartserverDevServerManager.js
- C:UsersMuhammed Tauqeer [email protected]
- C:UsersMuhammed Tauqeer [email protected]
- C:UsersMuhammed Tauqeer AliSocialSpherenode_modules@expoclibuildbincli
- C:UsersMuhammed Tauqeer AliSocialSpherenode_modulesexpobincli

The following is the image from web browser:
Error as Seen on Web Browser

Here’s what I’ve tried so far:

  1. Installed react and react-dom with npm install react react-dom.
  2. Cleared the Metro Bundler cache with npx expo start --clear.
  3. Ran npx expo-doctor, which didn’t find any errors or problems.

Besides these, I did also tried a few things from YouTube. But despite all these efforts, the error persists. This is an urgent project, and I’m really stuck. Any personal help or suggestions would be greatly appreciated!

Thanks in advance!

how to return characters/digits from the 3rd digit to second last in a string [closed]

I am having trouble in returning all characters between the 2nd and last for my output on javascript.

userInputStr = userInputStr[0] + userInputStr[userInput.length -1] + userInputStr.substring(2,length-1) + secondNum;

The substring seems fine to me, however the digits between the 2nd and last always end up missing when I run the code.

If anyone can see the problem please assist me, thanks

Tried adding digits from the third to second last, however when I run my code those digits are always missing.

Struggling to draw SVG onto an offscreen canvas in a web worker

I’ve been working from zero experience of web workers to now for longer than I’d like to admit and it has me defeated.

I want to move a long task, canvas.toBlob(/* jpeg stuff */) to a worker but sending an SVG to the worker, draw it onto the offscreen canvas, then convert to a JPEG and send it back to the main thread.

This is my code:

self.onmessage = async event => {
    const { imageSVG, width, height } = event.data;

    try {
        // Set up the offscreen canvas
        const offscreen = new OffscreenCanvas(width, height);
        const ctx = offscreen.getContext('2d');
        
        // Create the image and draw to canvas
        const imageSrc = `data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(imageSVG)))}`;

        const imgBlob = await fetch(imageSrc)
            .then(response => response.blob());

        const img = await createImageBitmap(imgBlob);

        ctx.drawImage(img, 0, 0, width, height);

        offscreen.convertToBlob({
            type: 'image/jpeg',
            quality: 1.0
        }).then(blob => {
            postMessage({ blob: blob });
        });
    }
    catch(error) {
        postMessage(`Error: ${error}`);
    }
};

The error I can’t get past is InvalidStateError: The source image could not be decoded. and I can’t find much online about what it means.

I did come across a github comment, now lost to a million closed tabs, that suggested wrapping the data URI in an SVGImageElement, but I don’t know what that means and they didn’t elaborate.

I am having a problem with Fullcalendar, eventMouseEnter method is not working

I am having a problem with Fullcalendar, eventMouseEnter method does not work.

I want that when the mouse hovers over the event, it changes color.

I am creating an event with Laravel, so I only put the javascript code.

I am using Full Calendar for the first time in my life.

$(document).ready(function() {
  var SITEURL = "{{ url('/') }}";

  $.ajaxSetup({
    headers: {
      'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
  });

  var calendar = $('#calendar').fullCalendar({
    editable: true,
    events: SITEURL + "/fullcalender",
    displayEventTime: false,
    editable: true,
    eventRender: function(event, element, view) {
      if (event.allDay === 'true') {
        event.allDay = true;
      } else {
        event.allDay = false;
      }
    },
    selectable: true,
    selectHelper: true,
    select: function(start, end, allDay) {
      var title = prompt('Event Title:');
      if (title) {
        var start = $.fullCalendar.formatDate(start, "Y-MM-DD");
        var end = $.fullCalendar.formatDate(end, "Y-MM-DD");
        $.ajax({
          url: SITEURL + "/fullcalenderAjax",
          data: {
            title: title,
            start: start,
            end: end,
            type: 'add'
          },
          type: "POST",
          success: function(data) {
            displayMessage("Event Created Successfully");
            calendar.fullCalendar('renderEvent', {
              id: data.id,
              title: title,
              start: start,
              end: end,
              allDay: allDay
            }, true);

            calendar.fullCalendar('unselect');
          }
        });
      }
    },
    eventDrop: function(event, delta) {
      var start = $.fullCalendar.formatDate(event.start, "Y-MM-DD");
      var end = $.fullCalendar.formatDate(event.end, "Y-MM-DD");

      $.ajax({
        url: SITEURL + '/fullcalenderAjax',
        data: {
          title: event.title,
          start: start,
          end: end,
          id: event.id,
          type: 'update'
        },
        type: "POST",
        success: function(response) {
          displayMessage("Event Updated Successfully");
        }
      });
    },
    eventClick: function(event) {
      var deleteMsg = confirm("Do you really want to delete?");
      if (deleteMsg) {
        $.ajax({
          type: "POST",
          url: SITEURL + '/fullcalenderAjax',
          data: {
            id: event.id,
            type: 'delete'
          },
          success: function(response) {
            calendar.fullCalendar('removeEvents', event.id);
            displayMessage("Event Deleted Successfully");
          }
        });
      }
    },
    eventMouseEnter: function(info) {
      info.el.style = "background-color: red;";
    }
  });

});

function displayMessage(message) {
  toastr.success(message, 'Event');
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.9.0/fullcalendar.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.9.0/fullcalendar.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css" />
<div class="container">
  <div class="card mt-5">
    <h3 class="card-header p-3">Laravel 11 FullCalender Tutorial Example - ItSolutionStuff.com</h3>
    <div class="card-body">
      <div id='calendar'></div>
    </div>
  </div>
</div>

Can someone help me and figure out where the problem is?

Node.js connection error because port already in use but i can`t find by what its been uses

i have mysql db to which i need to connect, yesterday everything was okay but today i just keep getting error with connection that this port is already in use
but i can`t find it

with chatgpt i try to change port in my program from 3001-3005 and it didnt help, also with task manager node.exe and with console to stop and start mysql service and also try to find this port with TCPView [enter image description here](https://i.sstatic.net/EDqDBkpZ.png)but it also doesnt appear.

Embedding Svelte 5 inside PHP (Imperative component API)

I’m trying to use Svelte 5 and SvelteKit inside PHP.

I don’t understand how to use the Imperative component API (https://svelte.dev/docs/svelte/imperative-component-api). Where do I put the following code? Do I put it in src/routes/main.js?

import { mount } from 'svelte';
import App from './App.svelte';

const app = mount(App, {
    target: document.querySelector('#app'),
    props: { some: 'property' }
});

If I use vite build -w to build the project, what is the path of the built JavaScript to put inside the PHP?

<body>
  <h1>
    <?php echo "Hello, $user"; ?>
  </h1>

  <div id="app">
  </div>

  <script src="/path/build/what-is-the-name-of-the-js-file-for-here.js"></script>
</body>

What do I set src/routes/+layout.js to? My assumption is that I should first try making an SPA (https://svelte.dev/docs/kit/single-page-apps) with the following for src/routes/+layout.js:

export const ssr = false;

I made a file with the JavaScript from the Imperative component API, but I don’t see it in build/.

How to detect an image redirection?

I have an Angular application where I want to fetch a users profile photo.

If I visit http://example.com/photo?userId=123456 directly it will either display an image at this URL, but if no photo is stored it will redirect to http://example.com/photo/default.jpg

How can I detect this redirection?

I’ve tried using fetch() but I get CORS errors. Setting fetch(this.imgUrl, { mode: 'no-cors' }) does not work because I get an opaque response which has no information about a redirection.

Simply running a method after the image loads works, but it provides no information about a redirection

const img = new Image();
img.src = this.imgUrl;
img.onload = (ev) => {
  console.log(ev);
  console.log(img);
};

This is what the ev returns:

{
  isTrusted: true,
  bubbles: false,
  cancelBubble: false,
  cancelable: false,
  composed: false,
  currentTarget: null,
  defaultPrevented: false,
  eventPhase: 0,
  returnValue: true,
  srcElement: null,
  target: null,
  timeStamp: 2268,
  type: "load",
}

How to run concurrently programatically without spawning new terminal windows?

I have an npm workspace where projects are in my packages folder and they all have a start script. I am trying to run them using the concurrently API, but I don’t want to spawn a new window for each command. I tried:

import { readdir } from "node:fs/promises";
import concurrently from "concurrently";

const packageDirs = await readdir("./packages");

const commands = packageDirs.map((dirName) => ({
  name: dirName,
  command: "start",
  cwd: `./packages/${dirName}`,
}));

concurrently(["npm run build:watch", ...commands], {
  raw: true,
  killOthers: true,
});