changing things in canvas by mouse movement using javaScript like size and location

I am just starting programming, and this is my second project—it’s a paint app. I saw the project on YouTube and cloned it in my own way. However, when I encountered problems, I referred to the video, as beginners should. But the video didn’t cover many features that were in my mind, like how I could move things inside the canvas and change their size after clicking a button.
this is my code

const canvas = document.querySelector(".canvas");
const ctx = canvas.getContext("2d");
const tools = document.querySelectorAll(".tool");
const fullColor = document.querySelector("#fill-color");
const brushSize = document.querySelector("#size-of-brush");
const colorBtns = document.querySelectorAll(".color .option");
const colorPicker = document.querySelector("#color-picker");
const clearCanvas = document.querySelector(".clear-canvas");
const saveCanvas = document.querySelector(".save-img");
// global variable
let method = "brush";
let draw = false;
let pervCorX;
let pervCorY;
let brushWidth = 5;
let oneDraw;
let color = "rgb(0, 0, 0)";

//canvas width and height
window.addEventListener("load", () => {
  canvas.width = canvas.offsetWidth;
  canvas.height = canvas.offsetHeight;
});

// confirm mouse down and change  the color and size of brush and ships
const mousedown = (event) => {
  draw = true;
  ctx.strokeStyle = color;
  ctx.fillStyle = color;
  pervCorX = event.offsetX;
  pervCorY = event.offsetY;
  ctx.beginPath();
  ctx.lineWidth = brushWidth;
  oneDraw = ctx.getImageData(0, 0, canvas.width, canvas.height);
};

// witch shape and width is clicked
tools.forEach((toolsBtn) => {
  toolsBtn.addEventListener("click", () => {
    document.querySelector(".active").classList.remove("active");
    toolsBtn.classList.add("active");
    method = toolsBtn.id;
    // console.log(method);
  });
});

// confirmation of stooping drawing
const mouseup = () => {
  draw = false;
};

// drawing rectangle circle triangle
const rectangle = (event) => {
  const x = event.offsetX;
  const y = event.offsetY;
  const width = pervCorX - event.offsetX;
  const height = pervCorY - event.offsetY;
  if (fullColor.checked) return ctx.fillRect(x, y, width, height);

  ctx.strokeRect(x, y, width, height);
};
const circle = (event) => {
  ctx.beginPath();
  console.log("hihi");
  const width = pervCorX - event.offsetX;
  const height = pervCorY - event.offsetY;
  let radius = Math.sqrt(width ** 2 + height ** 2);
  ctx.arc(pervCorX, pervCorY, radius, 0, 2 * Math.PI);
  if (fullColor.checked) return ctx.fill();
  ctx.stroke();
};
const triangle = (event) => {
  ctx.beginPath();
  ctx.moveTo(pervCorX, pervCorY);
  ctx.lineTo(event.offsetX, event.offsetY);
  ctx.lineTo(pervCorX * 2 - event.offsetX, event.offsetY);
  ctx.closePath();
  fullColor.checked ? ctx.fill() : ctx.stroke();
};

//checking what ship to draw
const startDrawing = (event) => {
  if (!draw) return;
  ctx.putImageData(oneDraw, 0, 0);

  if (method == "brush" || method == "eraser") {
    ctx.strokeStyle = method == "eraser" ? "#fff" : color;
    ctx.lineTo(event.offsetX, event.offsetY);
    ctx.stroke();
  } else if (method == "rectangle") {
    rectangle(event);
  } else if (method == "circle") {
    circle(event);
  } else if (method == "triangle") {
    triangle(event);
  }
};
colorBtns.forEach((btn) => {
  console.log(btn);
  btn.addEventListener("click", () => {
    document.querySelector(".selected").classList.remove("selected");
    btn.classList.add("selected");
    color = window.getComputedStyle(btn).backgroundColor;
  });
});
//changing color of ships  and brush
colorPicker.addEventListener("change", () => {
  colorPicker.parentElement.style.background = colorPicker.value;
  colorPicker.parentElement.click();
});
// checking if mouse down in canvas and give brush size
brushSize.addEventListener("change", () => (brushWidth = brushSize.value));
canvas.addEventListener("mousemove", startDrawing);
canvas.addEventListener("mousedown", mousedown);
canvas.addEventListener("mouseup", mouseup);
//save and clear canvas
clearCanvas.addEventListener("click", () => {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
});
saveCanvas.addEventListener("click", () => {
  const a = document.createElement("a");
  a.href = canvas.toDataURL("image/png");
  a.download = "canvas_image.png";
  a.click();
});




changing things in canvas by mouse movement using javaScript like size and location

I am just starting programming, and this is my second project—it’s a paint app. I saw the project on YouTube and cloned it in my own way. However, when I encountered problems, I referred to the video, as beginners should. But the video didn’t cover many features that were in my mind, like how I could move things inside the canvas and change their size after clicking a button.
this is my code

const canvas = document.querySelector(".canvas");
const ctx = canvas.getContext("2d");
const tools = document.querySelectorAll(".tool");
const fullColor = document.querySelector("#fill-color");
const brushSize = document.querySelector("#size-of-brush");
const colorBtns = document.querySelectorAll(".color .option");
const colorPicker = document.querySelector("#color-picker");
const clearCanvas = document.querySelector(".clear-canvas");
const saveCanvas = document.querySelector(".save-img");
// global variable
let method = "brush";
let draw = false;
let pervCorX;
let pervCorY;
let brushWidth = 5;
let oneDraw;
let color = "rgb(0, 0, 0)";

//canvas width and height
window.addEventListener("load", () => {
  canvas.width = canvas.offsetWidth;
  canvas.height = canvas.offsetHeight;
});

// confirm mouse down and change  the color and size of brush and ships
const mousedown = (event) => {
  draw = true;
  ctx.strokeStyle = color;
  ctx.fillStyle = color;
  pervCorX = event.offsetX;
  pervCorY = event.offsetY;
  ctx.beginPath();
  ctx.lineWidth = brushWidth;
  oneDraw = ctx.getImageData(0, 0, canvas.width, canvas.height);
};

// witch shape and width is clicked
tools.forEach((toolsBtn) => {
  toolsBtn.addEventListener("click", () => {
    document.querySelector(".active").classList.remove("active");
    toolsBtn.classList.add("active");
    method = toolsBtn.id;
    // console.log(method);
  });
});

// confirmation of stooping drawing
const mouseup = () => {
  draw = false;
};

// drawing rectangle circle triangle
const rectangle = (event) => {
  const x = event.offsetX;
  const y = event.offsetY;
  const width = pervCorX - event.offsetX;
  const height = pervCorY - event.offsetY;
  if (fullColor.checked) return ctx.fillRect(x, y, width, height);

  ctx.strokeRect(x, y, width, height);
};
const circle = (event) => {
  ctx.beginPath();
  console.log("hihi");
  const width = pervCorX - event.offsetX;
  const height = pervCorY - event.offsetY;
  let radius = Math.sqrt(width ** 2 + height ** 2);
  ctx.arc(pervCorX, pervCorY, radius, 0, 2 * Math.PI);
  if (fullColor.checked) return ctx.fill();
  ctx.stroke();
};
const triangle = (event) => {
  ctx.beginPath();
  ctx.moveTo(pervCorX, pervCorY);
  ctx.lineTo(event.offsetX, event.offsetY);
  ctx.lineTo(pervCorX * 2 - event.offsetX, event.offsetY);
  ctx.closePath();
  fullColor.checked ? ctx.fill() : ctx.stroke();
};

//checking what ship to draw
const startDrawing = (event) => {
  if (!draw) return;
  ctx.putImageData(oneDraw, 0, 0);

  if (method == "brush" || method == "eraser") {
    ctx.strokeStyle = method == "eraser" ? "#fff" : color;
    ctx.lineTo(event.offsetX, event.offsetY);
    ctx.stroke();
  } else if (method == "rectangle") {
    rectangle(event);
  } else if (method == "circle") {
    circle(event);
  } else if (method == "triangle") {
    triangle(event);
  }
};
colorBtns.forEach((btn) => {
  console.log(btn);
  btn.addEventListener("click", () => {
    document.querySelector(".selected").classList.remove("selected");
    btn.classList.add("selected");
    color = window.getComputedStyle(btn).backgroundColor;
  });
});
//changing color of ships  and brush
colorPicker.addEventListener("change", () => {
  colorPicker.parentElement.style.background = colorPicker.value;
  colorPicker.parentElement.click();
});
// checking if mouse down in canvas and give brush size
brushSize.addEventListener("change", () => (brushWidth = brushSize.value));
canvas.addEventListener("mousemove", startDrawing);
canvas.addEventListener("mousedown", mousedown);
canvas.addEventListener("mouseup", mouseup);
//save and clear canvas
clearCanvas.addEventListener("click", () => {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
});
saveCanvas.addEventListener("click", () => {
  const a = document.createElement("a");
  a.href = canvas.toDataURL("image/png");
  a.download = "canvas_image.png";
  a.click();
});




“Error creating bet: TypeError – Cannot read properties of undefined (reading ‘toString’)”

Introduction:
I am facing a problem when creating a bet in my Node.js application. The code related to the POST route /api/bets is generating an error that I cannot resolve.

Relevant Code:
Here is the relevant code snippet from the POST /api/bets route:

const express = require("express");
const router = express.Router();
const Bet = require("../models/bet");
const Game = require("../models/game");
const Odd = require("../models/odd");
const User = require("../models/user");

const handleError = (res, statusCode, errorMessage) => {
  console.error(errorMessage);
  res.status(statusCode).json({ error: errorMessage });
};

const verifyGameExists = async (gameId) => {
  const game = await Game.findById(gameId);
  if (!game) throw "Jogo não encontrado.";
};

const verifyOddExists = async (oddId) => {
  const odd = await Odd.findById(oddId);
  if (!odd) throw "Odd não encontrada.";
};

const verifyUserBalance = async (userId, betAmount) => {
  try {
    console.log('Verificando saldo do usuário. UserID:', userId);

    const user = await User.findById(userId);

    console.log('User encontrado:', user);

    if (!user || !user.balance || user.balance < betAmount) {
      console.log('Saldo insuficiente. User ou balance inválido.');

      throw "Saldo insuficiente para a aposta.";
    }
  } catch (error) {
    console.error(`Erro ao verificar o saldo do usuário: ${error}`);

    throw `Erro ao verificar o saldo do usuário: ${error}`;
  }
};


router.get("/", async (req, res) => {
  try {
    const bets = await Bet.find({ userId: req.user._id })
      .populate({
        path: "gameId",
        select: "name dateTime teamA teamB",
      })
      .populate({
        path: "oddId",
        select: "teamAOdd teamBOdd drawOdd",
      });

      const formattedBets = bets.map((bet) => ({
        betId: bet._id ? bet._id.toString() : null,
        gameId: bet.gameId,
        oddId: bet.oddId,
        betAmount: bet.betAmount,
        betType: bet.betType,
        status: bet.status,
        dateTime: bet.dateTime,
      }));

    res.status(200).json(formattedBets);
  } catch (error) {
    handleError(res, 500, "Erro ao obter a lista de apostas.");
  }
});

router.post("/", async (req, res) => {
  try {
    const { gameId, oddId, betAmount, betType } = req.body;

    console.log('User object in create bet route:', req.user);
    console.log('OddId in create bet route:', oddId);

    if (!req.user || !req.user.userId) {
      console.log('User ID not defined. Sending error response.');
      return handleError(
        res,
        500,
        "Erro ao criar a aposta: ID do usuário não está definido."
      );
    }

    // Verificar se a Odd existe
    const odd = await Odd.findById(oddId);
    console.log('Response from database:', odd);

    console.log('Odd found:', odd);

    if (!odd) {
      console.log('Odd not found. Sending error response.');
      return handleError(
        res,
        404,
        "Erro ao criar a aposta: Odd não encontrada."
      );
    }

    await verifyGameExists(gameId);
    await verifyOddExists(oddId);
    await verifyUserBalance(req.user.userId, betAmount);

    const userId = req.user && req.user._id.toString();
    console.log('UserID ao criar aposta:', userId);

    const newBet = new Bet({
      userId,
      gameId,
      oddId,
      betAmount,
      betType,
      status: "pending",
      dateTime: new Date(),
    });

    console.log('Objeto da Nova Aposta:', newBet);

    await newBet.save();

    const user = await User.findById(req.user._id);
    const userBalance = user.balance;
    const updatedBalance = userBalance - betAmount;
    await User.findByIdAndUpdate(req.user._id, { balance: updatedBalance });


    res
      .status(201)
      .json({
        message: "Aposta criada com sucesso.",
        betId: newBet._id.toString(),
      });
  } catch (error) {
    handleError(res, 500, `Erro ao criar a aposta: ${error}`);
  }
});

module.exports = router;

Console

Servidor rodando na porta 3000  
Token recebido: Bearer   eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTVlMjk2MzRhZGRjNjMyMTUxNDM4ZjIiLCJpYXQiOjE3MDA3NzI2MDMsImV4cCI6MTcwMDc3NjIwM30.qg56kCr8OjRr3NFTq9m83Ft-OCmwBz4yHaW8QrPyAns  
Token verificado com sucesso. Usuário: {  
  userId: '655e29634addc632151438f2',  
  iat: 1700772603,  
  exp: 1700776203  
}  
User object in create bet route: {  
  userId: '655e29634addc632151438f2',  
  iat: 1700772603,  
  exp: 1700776203  
}  
OddId in create bet route: 655c860bfb66e6a152662866  
Response from database: {  
  _id: new ObjectId('655c860bfb66e6a152662866'),  
  gameId: new ObjectId('6557a8c7650c8c58682b46c8'),  
  teamAOdd: 2.5,  
  teamBOdd: 1.8,  
  drawOdd: 3,  
  __v: 0  
}  
Odd found: {  
  _id: new ObjectId('655c860bfb66e6a152662866'),  
  gameId: new ObjectId('6557a8c7650c8c58682b46c8'),  
  teamAOdd: 2.5,  
  teamBOdd: 1.8,  
  drawOdd: 3,  
  __v: 0  
}  
Verificando saldo do usuário. UserID: 655e29634addc632151438f2  
User encontrado: {  
  _id: new ObjectId('655e29634addc632151438f2'),  
  username: 'Diogo Pimenta',  
  password: '$2a$10$4/yOtaQAW.W5A8sN2Y4a4.0SWm5s839HogIFQFjTzy2z9FJwFx1ya',  
  role: 'user',  
  balance: 1000,  
  __v: 0  
}  
Erro ao criar a aposta: TypeError: Cannot read properties of undefined   (reading 'toString')  


Problem description:
When trying to create a bet, I get an error TypeError: Cannot read properties of undefined (reading ‘toString’). I am having difficulty identifying the root cause of the problem.

Ambiente:
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]

The expected behavior was for the bet to be created successfully, but the mentioned error is occurring, preventing the operation from completing.

“Error creating bet: TypeError – Cannot read properties of undefined (reading ‘toString’)”

Introduction:
I am facing a problem when creating a bet in my Node.js application. The code related to the POST route /api/bets is generating an error that I cannot resolve.

Relevant Code:
Here is the relevant code snippet from the POST /api/bets route:

const express = require("express");
const router = express.Router();
const Bet = require("../models/bet");
const Game = require("../models/game");
const Odd = require("../models/odd");
const User = require("../models/user");

const handleError = (res, statusCode, errorMessage) => {
  console.error(errorMessage);
  res.status(statusCode).json({ error: errorMessage });
};

const verifyGameExists = async (gameId) => {
  const game = await Game.findById(gameId);
  if (!game) throw "Jogo não encontrado.";
};

const verifyOddExists = async (oddId) => {
  const odd = await Odd.findById(oddId);
  if (!odd) throw "Odd não encontrada.";
};

const verifyUserBalance = async (userId, betAmount) => {
  try {
    console.log('Verificando saldo do usuário. UserID:', userId);

    const user = await User.findById(userId);

    console.log('User encontrado:', user);

    if (!user || !user.balance || user.balance < betAmount) {
      console.log('Saldo insuficiente. User ou balance inválido.');

      throw "Saldo insuficiente para a aposta.";
    }
  } catch (error) {
    console.error(`Erro ao verificar o saldo do usuário: ${error}`);

    throw `Erro ao verificar o saldo do usuário: ${error}`;
  }
};


router.get("/", async (req, res) => {
  try {
    const bets = await Bet.find({ userId: req.user._id })
      .populate({
        path: "gameId",
        select: "name dateTime teamA teamB",
      })
      .populate({
        path: "oddId",
        select: "teamAOdd teamBOdd drawOdd",
      });

      const formattedBets = bets.map((bet) => ({
        betId: bet._id ? bet._id.toString() : null,
        gameId: bet.gameId,
        oddId: bet.oddId,
        betAmount: bet.betAmount,
        betType: bet.betType,
        status: bet.status,
        dateTime: bet.dateTime,
      }));

    res.status(200).json(formattedBets);
  } catch (error) {
    handleError(res, 500, "Erro ao obter a lista de apostas.");
  }
});

router.post("/", async (req, res) => {
  try {
    const { gameId, oddId, betAmount, betType } = req.body;

    console.log('User object in create bet route:', req.user);
    console.log('OddId in create bet route:', oddId);

    if (!req.user || !req.user.userId) {
      console.log('User ID not defined. Sending error response.');
      return handleError(
        res,
        500,
        "Erro ao criar a aposta: ID do usuário não está definido."
      );
    }

    // Verificar se a Odd existe
    const odd = await Odd.findById(oddId);
    console.log('Response from database:', odd);

    console.log('Odd found:', odd);

    if (!odd) {
      console.log('Odd not found. Sending error response.');
      return handleError(
        res,
        404,
        "Erro ao criar a aposta: Odd não encontrada."
      );
    }

    await verifyGameExists(gameId);
    await verifyOddExists(oddId);
    await verifyUserBalance(req.user.userId, betAmount);

    const userId = req.user && req.user._id.toString();
    console.log('UserID ao criar aposta:', userId);

    const newBet = new Bet({
      userId,
      gameId,
      oddId,
      betAmount,
      betType,
      status: "pending",
      dateTime: new Date(),
    });

    console.log('Objeto da Nova Aposta:', newBet);

    await newBet.save();

    const user = await User.findById(req.user._id);
    const userBalance = user.balance;
    const updatedBalance = userBalance - betAmount;
    await User.findByIdAndUpdate(req.user._id, { balance: updatedBalance });


    res
      .status(201)
      .json({
        message: "Aposta criada com sucesso.",
        betId: newBet._id.toString(),
      });
  } catch (error) {
    handleError(res, 500, `Erro ao criar a aposta: ${error}`);
  }
});

module.exports = router;

Console

Servidor rodando na porta 3000  
Token recebido: Bearer   eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTVlMjk2MzRhZGRjNjMyMTUxNDM4ZjIiLCJpYXQiOjE3MDA3NzI2MDMsImV4cCI6MTcwMDc3NjIwM30.qg56kCr8OjRr3NFTq9m83Ft-OCmwBz4yHaW8QrPyAns  
Token verificado com sucesso. Usuário: {  
  userId: '655e29634addc632151438f2',  
  iat: 1700772603,  
  exp: 1700776203  
}  
User object in create bet route: {  
  userId: '655e29634addc632151438f2',  
  iat: 1700772603,  
  exp: 1700776203  
}  
OddId in create bet route: 655c860bfb66e6a152662866  
Response from database: {  
  _id: new ObjectId('655c860bfb66e6a152662866'),  
  gameId: new ObjectId('6557a8c7650c8c58682b46c8'),  
  teamAOdd: 2.5,  
  teamBOdd: 1.8,  
  drawOdd: 3,  
  __v: 0  
}  
Odd found: {  
  _id: new ObjectId('655c860bfb66e6a152662866'),  
  gameId: new ObjectId('6557a8c7650c8c58682b46c8'),  
  teamAOdd: 2.5,  
  teamBOdd: 1.8,  
  drawOdd: 3,  
  __v: 0  
}  
Verificando saldo do usuário. UserID: 655e29634addc632151438f2  
User encontrado: {  
  _id: new ObjectId('655e29634addc632151438f2'),  
  username: 'Diogo Pimenta',  
  password: '$2a$10$4/yOtaQAW.W5A8sN2Y4a4.0SWm5s839HogIFQFjTzy2z9FJwFx1ya',  
  role: 'user',  
  balance: 1000,  
  __v: 0  
}  
Erro ao criar a aposta: TypeError: Cannot read properties of undefined   (reading 'toString')  


Problem description:
When trying to create a bet, I get an error TypeError: Cannot read properties of undefined (reading ‘toString’). I am having difficulty identifying the root cause of the problem.

Ambiente:
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]

The expected behavior was for the bet to be created successfully, but the mentioned error is occurring, preventing the operation from completing.

How to get the time to load the iframe using onload

I have a lisst of urls that I have to use as a source for the iframe. So after creating child and appending to the DOM, I run the onload function to do further processing but the time that I get for each iframe is not correct. The code is as follows –

`var s = document.createElement('iframe');
document.body.appendChild(s);
s.onload = function() {
var totalTime = performance.now() - startTime;
console.log(document.body);
console.log(totalTime, element);
timestamps.push(totalTime);
}
s.src=url;
var startTime = performance.now();
}`

So here URL is one of the urls from that array and I have to get the time to check how much time a iframe (url) takes to load.

To test the time, in of the url endpoint I put a sleep function so that I can validate that the time to load that is more than any other case. But it never happens that I get the max time on that endpoint.

how to create image tracker with ar.js

I hope you are all doing well.
I am new to the world of javascript and web design. I am planning to create an augmented reality for my site. At first, I used unity and wanted to get webgl output. But due to the use of vofuria engine, I understood that webgl will not be usable. That’s why I went to Ar.js. But unfortunately, no matter how hard I try and follow different templates, I can’t find a way. I have put the code I use here and also put all the required data publicly in AWS storage space. This information and data have been uploaded from this github itself. Thank you very much for your help and guidance

<script src="https://cdn.jsdelivr.net/gh/aframevr/[email protected]/dist/aframe-master.min.js"></script>

<style>
  .arjs-loader {
    height: 100%;
    width: 100%;
    position: absolute;
    top: 0;
    left: 0;
    background-color: rgba(0, 0, 0, 0.8);
    z-index: 9999;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .arjs-loader div {
    text-align: center;
    font-size: 1.25em;
    color: white;
  }
</style>

<!-- rawgithack development URL -->
<!--<script src='https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar.js'></script>-->
<script src='https://s3.us-west-1.amazonaws.com/ar.js/trex-sample/aframe-ar-nft.js'></script>


<body style='margin : 0px; overflow: hidden;'>
   <!-- minimal loader shown until image descriptors are loaded -->
  <div class="arjs-loader">
    <div>Loading, please wait...</div>
  </div>
    <a-scene
        vr-mode-ui='enabled: false;'
        renderer="logarithmicDepthBuffer: true; precision: medium;"
        embedded arjs='trackingMethod: best; sourceType: webcam; debugUIEnabled: false;'>

        <!-- use rawgithack to retrieve the correct url for nft marker (see 'pinball' below) -->
        <a-nft
            type='nft' url='https://s3.us-west-1.amazonaws.com/ar.js/trex-sample/trex/trex-image/trex' 
            smooth='true' smoothCount='10' smoothTolerance='0.01' smoothThreshold='5'>
            <a-entity
                gltf-model='https://s3.us-west-1.amazonaws.com/ar.js/trex-sample/trex/scene.gltf'
                scale="5 5 5"
                position="150 300 -100"
                >
            </a-entity>
        </a-nft>
        <a-entity camera></a-entity>
    </a-scene>
</body>

Problem sending base64 encoded audio file via FormData

I am working on an Ionic application that uses Capacitor to record audio and then transcribe it to the server using OpenIA API. The audio recording is successful, and I get a base64 encoded file with the following structure:

{
  recordDataBase64: "BASE64_STRING",
  msDuration: 10000,
  mimeType: "audio/webm" // can be wav, mp3 or webm
}

Now I am trying to send this audio file to my server via a POST request using FormData in Ionic with react. I have implemented the following code:

class Utils {
  static async transcribe(value: {
    recordDataBase64: string;
    msDuration: number;
    mimeType: string;
  }): Promise<string | null> {
    try {
      const fileName = 'recording.' + value.mimeType.split('/')[1];
  
      // Crear un objeto FormData
      const formData = new FormData();
  
      // Decodificar la cadena base64 a un Blob
      const blob = this.base64toBlob(value.recordDataBase64, value.mimeType);
  
      // Adjuntar el Blob al FormData con un nombre de archivo "file"
      formData.append('file', blob, fileName);
  
      // Realizar la solicitud POST
      const response = await ApiRequest('/transcribe', {
        method: 'POST',
        body: formData,
        headers: {
          'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW',
        },
      });
  
      // Obtener la transcripción del cuerpo de la respuesta
      const transcription = await response.json();
  
      console.log(transcription);
  
      return transcription;
    } catch (error) {
      console.error('Error al transcribir el audio:', error);
      return null;
    }
  }
  
// Función para convertir una cadena base64 a un Blob
static base64toBlob(base64: string, mimeType: string): Blob {
  const byteCharacters = atob(base64);
  const byteArrays = [];

  for (let offset = 0; offset < byteCharacters.length; offset += 512) {
    const slice = byteCharacters.slice(offset, offset + 512);

    const byteNumbers = new Array(slice.length);
    for (let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }

    const byteArray = new Uint8Array(byteNumbers);
    byteArrays.push(byteArray);
  }

  return new Blob(byteArrays, { type: mimeType });
}
}

However, I am getting undefined as a response from the server, but when I use PostMan to test it works correctly.

enter image description here
enter image description here

the first log is using the webapp, the last is using postman
enter image description here

Can anyone help me identify why I am getting undefined and how I can correct this?

Fetching Multiple Media Content from an Instagram Post in SwiftUI

I’m working on a SwiftUI application that fetches media content from Instagram posts. While I can successfully retrieve a single reel from a post, my code struggles with posts containing more than two videos. The main challenge is fetching all video URLs from a multi-media post without manually clicking the ‘next’ button, as the content loads dynamically in the DOM.

Here’s the part of my code that deals with media fetching:

import SwiftUI
import WebKit

class Coordinator: NSObject, WKNavigationDelegate {
    private let scripts = [
        "mediaSrcScript": """
        var postContainer = document.querySelector('article'); // Targeting the main post container
        var nextButton = postContainer.querySelector('button[aria-label="Next"]');
        var videoUrls = [];
        var maxClicks = 10; // Limit the number of iterations to prevent infinite loops

        function collectVideos() {
            var videoElements = postContainer.querySelectorAll('video');
            Array.from(videoElements).forEach(video => {
                var src = video.getAttribute('src');
                if (!videoUrls.includes(src)) {
                    videoUrls.push(src);
                }
            });
        }

        function clickNextAndCollect() {
            if (nextButton && maxClicks > 0) {
                nextButton.click();
                maxClicks--;
                setTimeout(() => {
                    collectVideos();
                    clickNextAndCollect();
                }, 1000); // Delay to allow for loading new content
            }
        }

        collectVideos();
        clickNextAndCollect();

        JSON.stringify(videoUrls);
        """,
    ]
    
    // Function called when a web page finishes loading
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        startElementCheck(webView)
    }
    
    private func startElementCheck(_ webView: WKWebView) {
        let elementCheckScript = """
            var profilePicExists = Array.from(document.querySelectorAll('img')).some(img => img.alt.includes('profile picture'));
            profilePicExists; // Returns true if the profile picture exists
        """
        
        webView.evaluateJavaScript(elementCheckScript) { [weak self] (result, error) in
            guard let self = self, let elementReady = result as? Bool else {
                return
            }
            
            if elementReady {
                // Profile picture found - start executing your scripts
                self.executeScripts(webView)
            }
        }
    }

    // Function to execute the scripts
    private func executeScripts(_ webView: WKWebView) {
        for (key, script) in self.scripts {
            webView.evaluateJavaScript(script) { (result, error) in
                if let resultString = result as? String {
                    // Process the result
                    print("(key): (resultString)")
                } else if let error = error {
                    print("Error executing script (key): (error)")
                }
            }
        }
    }
}

// WebView to integrate WKWebView in SwiftUI
struct WebView: UIViewRepresentable {
    let url: URL

    func makeUIView(context: Context) -> WKWebView {
        let webView = WKWebView()
        webView.navigationDelegate = context.coordinator
        return webView
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        let request = URLRequest(url: url)
        uiView.load(request)
    }

    func makeCoordinator() -> Coordinator {
        return Coordinator()
    }
}

// ContentView to display the WebView
struct ContentView: View {
    var body: some View {
        WebView(url: URL(string: "https://www.instagram.com/p/Cz45oeXJhj8/?utm_source=ig_web_copy_link")!)
    }
}

The code successfully gets the first two video URLs, but then I have to start clicking ‘next’ to fetch more, which isn’t ideal or is not working. I’m looking for a way to automatically load and process all video URLs from a post. Does anyone know a more efficient method to fix this, possibly without relying on UI interactions?

Antd Tooltip gets stuck when component moves onclick

I have a button with an Antd tooltip, like this:

<Tooltip title="Some text">
  <button onClick={openNotes}><Icon icon="notes" /></button>
</Tooltip>

When you click the button, the openNotes function makes some other component appear on screen so it moves the Tooltip like 200px to the left.

This makes the tooltip get stuck unless you hover off it, then hover on, then off again.

Is there any solution to this? I tried setting the mouseLeave delay to 0 but it still happens.

Problem with accessing an array in javascript

I want to build a web-remote for the DAW Reaper, using Reapers WebRC.

How it works in basic you can read about here:

In my case I want to access the markers set in Reaper.

The minimum example of the code I use you find here:

<!doctype html>
<html>
<head>

<script src="main.js"></script>
<script type="text/javascript">
function wwr_onreply(results) {
  var ar = results.split("n");

  for (var i = 0; i < ar.length; i++) {
    var tok = ar[i].split("t");
    if (tok.length > 0)
      switch (tok[0]) {
        case "MARKER":
          document.getElementById("marker").innerHTML = tok;
          break;
      }
  }
}

wwr_req_recur("MARKER", 1000);
wwr_start();
</script>
</head>

<body>

<p>tok of "MARKER": <div id="marker"></div></p>

</body>

</html>

So Reaper passes the queried in a single line of text.
Each parameter (e.g. “TRANSPORT”, “TRACKS”, “MARKERS”, etc.) is divided by “n”.
If a parameter contains multiple parameters (like different markers), they are divided by “t”.

Now the results get split by “n” and stored in the array “ar”.
After that, if containing multiples, they get split by “t” and stored in the array “tok”.

My problem: I can only access the last marker in the “tok”.
The tok.length is always ‘5’ (Marker, Marker name, id, position, color), no matter how many markers are in the project.
When I use “alert(tok.length);”, the message windows opens and by clicking ok I can step through all the markers.

Can anyone help me, how I can access the other entries in “tok”?

I tried like with nested array (tok[2][3];), but it didn’t help…

I tried to display “tok” with document.getElementById("element").innerHTML = tok and document.getElementById("element").innerHTML = tok[x][y]

I tried to display via “alert(tok)”

A4 page height is not considered when generating dynamic page number using javascript during print event

I’m generating A4 invoice using HTML, CSS and JS. The invoice is getting generated as expected during print preview. However page number is not aligned and extra empty pages are generated automatically.

Here is my code snippet:

<html>

<head>
    <script>function setPrintStyles(pagesize, standardSize) {
            var documentHeight = standardSize ? '' : (document.getElementsByTagName('html')[0].offsetHeight / 2) + 100 + 'px';
            var bodySize = standardSize ? '' : 'body { width: ' + pagesize + '; }';
            var css = `@media print { @page { size: ${pagesize} ${documentHeight}; } ${bodySize} }`,
                head = document.head || document.getElementsByTagName('head')[0],
                style = document.createElement('style');
            head.appendChild(style);
            style.type = 'text/css';
            style.appendChild(document.createTextNode(css));
        }</script>
    <style type="text/css">
        @media print {
            #section-to-print {
                position: absolute;
                left: 0;
                top: 0;
            }

            body {
                font-family: Calibri, monospace;
                font-size: 0.8rem;
                margin: 1rem;
                border: 1px solid;
            }

            body ol {
                list-style: none;
                padding-left: 0;
                margin: 0.5rem 0;
            }

            table {
                width: 100%;
                height: 100%;
                border-collapse: collapse;
                page-break-inside: auto;
            }

            td section div {
                page-break-inside: avoid;
            }

            thead {
                display: table-header-group;
            }

            tfoot {
                display: table-footer-group;
            }

            header {
                display: flex;
                flex-direction: column;
                font-weight: normal;
            }

            #brand {
                border-bottom: 1px solid;
                padding: 0.25rem 0.5rem;
                text-transform: uppercase;
                font-weight: bold;
            }

            #invoicedetails {
                display: grid;
                grid: "shop customer invoice";
                grid-template-columns: repeat(3, 1fr);
                padding: 0 0.5rem;
                border-bottom: 1px solid;
            }

            #shop {
                text-align: left;
            }

            #customer {
                border: 1px solid;
                border-top: 0;
                border-bottom: 0;
                padding-left: 0.5rem;
                text-align: center;
            }

            #invoice {
                text-align: right;
            }

            table tbody td {
                height: 100%;
                display: flex;
                flex-direction: column;
                justify-content: space-between;
            }

            main {
                display: block;
                height: 100%;
            }

            #invoiceitems {
                display: block;
                height: 100%;
                text-transform: uppercase;
            }

            #itemscontent {
                height: 100%;
                display: grid;
                grid: "sno isbnno title price quantity amount";
                /*Below line is added as inline style in A4 invoice component*/
                /*grid-template-rows: repeat(2, minmax(1rem, max-content)) auto repeat(2, minmax(1rem, max-content));*/
                /*grid-template-columns: minmax(min-content, max-content) minmax(min-content, auto) max-content max-content max-content max-content max-content max-content;*/
                grid-auto-rows: minmax(1rem, max-content);
                grid-column-gap: 1px;
                align-items: center;
            }

            #itemscontent>div {
                display: flex;
                align-items: center;
                border: 1px solid;
                height: 100%;
                border-top: 0;
                border-right: 0;
                padding: 0 0.25rem;
            }

            .border-left-0 {
                border-left: 0 !important;
            }

            .border-bottom-0 {
                border-bottom: 0 !important;
            }

            .span-4 {
                grid-column-start: span 4;
            }

            .flex-end {
                justify-content: flex-end;
            }

            footer {
                display: flex;
                flex-direction: column;
            }

            #itemsfooter {
                display: flex;
                justify-content: space-between;
                align-items: center;
                text-transform: uppercase;
                border-top: 1px solid;
            }

            #itemsfooter>div {
                align-self: stretch;
                display: flex;
                align-items: center;
                padding: 0 0.5rem;
            }

            #amountinwords {
                flex: 75%;
            }

            #totalamount {
                flex: 25%;
                text-align: right;
                border-left: 1px solid black;
            }

            #totalamount ol {
                width: 100%;
            }

            #totalamount ol li:last-child {
                font-size: x-large;
            }

            #invoiceinformation {
                display: flex;
                justify-content: end;
                padding: 0 0.5rem;
                border-top: 1px solid;
                border-bottom: 1px solid;
            }

            #signature {
                padding-left: 0.5rem;
            }

            #message {
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 0 0.5rem;
            }
        }
    </style>
    <style type="text/css">
        @media print {
            @page {
                size: A4;
            }
        }
    </style>
    <style>
        html {
            height: 297mm !important;
            overflow-y: scroll;
        }
    </style>
</head>

<body><!--!-->
    <table>
        <thead>
            <tr>
                <th>
                    <header>
                        <section id="brand"></section><!--!-->
                        <section id="invoicedetails">
                            <section id="shop">
                                <ol>
                                    <li>From</li><!--!-->
                                    <li><b>ABC</b></li><!--!-->
                                    <li>Address:</li><!--!-->
                                    <li>Phone:</li><!--!-->
                                    <li>Mobile:</li>
                                </ol>
                            </section><!--!-->
                            <section id="customer">
                                <ol>
                                    <li>To</li><!--!-->
                                    <li><b>DEF </b></li><!--!-->
                                    <li>Mobile: </li>
                                </ol>
                            </section><!--!-->
                            <section id="invoice">
                                <ol id="invoice-details"><!--!-->
                                    <li>Invoice Details</li>
                                    <li>Invoice No: <b>18/2023-24</b></li><!--!-->
                                    <li>Invoice Date: <b>17 Nov 2023</b></li><!--!-->
                                    <li>Payment Mode: <b>Cash</b></li><!--!-->
                                    <li>Payment Status: Paid</li><!--!-->
                                    <li id="page-number"><br/></li>
                                </ol>
                            </section>
                        </section>
                    </header>
                </th>
            </tr>
        </thead><!--!-->
        <tbody>
            <tr>
                <td>
                    <main>
                        <section id="invoiceitems">
                            <section id="itemscontent"
                                style="grid-template-rows: repeat(5, minmax(1rem, max-content)) auto repeat(2, minmax(1rem, max-content)); grid-template-columns: minmax(min-content, max-content) minmax(min-content, max-content) minmax(min-content, auto) max-content max-content max-content">
                                <!--!-->
                                <div class="border-left-0">S.No</div>
                                <!--!-->
                                <div>ISBN No</div>
                                <!--!-->
                                <div>Title</div>
                                <!--!-->
                                <div>Price</div>
                                <!--!-->
                                <div>Quantity</div>
                                <!--!-->
                                <div>Amount</div>
                                <div class="border-left-0 border-bottom-0">1</div><!--!-->
                                <div class="border-bottom-0"></div><!--!-->
                                <div class="border-bottom-0">Another Test</div><!--!-->
                                <div class="flex-end border-bottom-0">10.00</div><!--!-->
                                <div class="flex-end border-bottom-0">1</div><!--!-->
                                <div class="flex-end border-bottom-0">10.00</div>
                                <div class="border-left-0 border-bottom-0">2</div><!--!-->
                                <div class="border-bottom-0"></div><!--!-->
                                <div class="border-bottom-0">Another Test</div><!--!-->
                                <div class="flex-end border-bottom-0">10.00</div><!--!-->
                                <div class="flex-end border-bottom-0">1</div><!--!-->
                                <div class="flex-end border-bottom-0">10.00</div>
                                <div class="border-left-0 border-bottom-0">3</div><!--!-->
                                <div class="border-bottom-0"></div><!--!-->
                                <div class="border-bottom-0">Another Test</div><!--!-->
                                <div class="flex-end border-bottom-0">10.00</div><!--!-->
                                <div class="flex-end border-bottom-0">1</div><!--!-->
                                <div class="flex-end border-bottom-0">10.00</div>
                                <div class="border-left-0 border-bottom-0">4</div><!--!-->
                                <div class="border-bottom-0"></div><!--!-->
                                <div class="border-bottom-0">Another Test</div><!--!-->
                                <div class="flex-end border-bottom-0">10.00</div><!--!-->
                                <div class="flex-end border-bottom-0">1</div><!--!-->
                                <div class="flex-end border-bottom-0">10.00</div><!--!-->
                                <div class="border-left-0"></div>
                                <div></div>
                                <div></div>
                                <div></div>
                                <div></div>
                                <div></div>

                                <!--!-->
                                <div class="border-left-0 flex-end span-4">Sub Total</div>
                                <div class="flex-end">4</div><!--!-->
                                <div class="flex-end">40.00</div>
                                <div class="border-left-0 flex-end span-4">Discount (10.00%)</div><!--!-->
                                <div></div>
                                <div class="flex-end">-3.00</div>
                            </section>
                        </section>
                    </main><!--!-->
                    <footer>
                        <section id="itemsfooter">
                            <div id="amountinwords">
                                <ol>
                                    <li><small>Total Amount in Words (INR)</small></li><!--!-->
                                    <li><b>thirty seven ONLY</b></li>
                                </ol>
                            </div><!--!-->
                            <div id="totalamount">
                                <ol><!--!-->
                                    <li><small>Total Amount</small></li>
                                    <li><b>₹37.00</b></li>
                                </ol>
                            </div>
                        </section><!--!-->
                        <section id="invoiceinformation">
                            <div id="signature"><text>for <!--!--><br><br><br>Authorized
                                    Signatory</text></div>
                        </section><!--!-->
                        <!--!-->
                        <section id="message">
                            <div><small>THANK YOU FOR THE BUSINESS</small></div>
                            <div><small>THIS IS A COMPUTER GENERATED INVOICE</small></div>
                        </section>
                    </footer>
                </td>
            </tr>
        </tbody>
    </table>
    <div id="dpi" style="height: 1in; left: -100%; position: absolute; top: -100%; width: 1in;"></div>
    <script>window.print();</script>
    <script>window.onbeforeprint = addPageNumbers;
        window.onafterprint = removePageNumbers;
        function removePageNumbers() {
            document.querySelectorAll('.dynamic-page-number').forEach(function (li) {
                li.remove();
            });
        }
        function addPageNumbers() {
            var dpi = document.getElementById("dpi").offsetHeight;
            console.log(dpi);
            var sheetHeightInMM = 297;
            var mmPerInch = 25.4;
            var pixels = (sheetHeightInMM * dpi) / mmPerInch;
            var bodyHeight = document.getElementsByTagName('body')[0].scrollHeight;
            console.log(bodyHeight);
            var totalPages = Math.ceil(bodyHeight / pixels);
            console.log(totalPages);
            for (var i = 1; i <= totalPages; i++) {
                var pageNumberLi = document.createElement("li");
                var pageNumber = document.createTextNode("Page " + i + " of " + totalPages);
                pageNumberLi.classList.add('dynamic-page-number');
                pageNumberLi.style.paddingTop = '5px'; // added to adjust spacing between previous li element in dom
                pageNumberLi.style.position = "absolute";
                var offsetTop = document.getElementById("page-number").offsetTop + "px";
                console.log(offsetTop);
                pageNumberLi.style.top = `calc((${i - 1} * ${sheetHeightInMM}mm) + ${offsetTop} - ${i * 1}rem)`;
                pageNumberLi.style.right = '1.5rem'; // 1rem body right margin + 0.5rem header right padding
                pageNumberLi.appendChild(pageNumber);
                document.getElementById("invoice-details").appendChild(pageNumberLi);
            }
        }</script>
</body>

</html>

Issue I’m facing:

the above code will generate single page A4 invoice. But this generates two pages in print preview. The page number can also be seen in invoice.

Page 1:

enter image description here

Page 2:

enter image description here

Script used for page number generation:

function addPageNumbers() {
    var dpi = document.getElementById("dpi").offsetHeight;
    console.log(dpi);
    var sheetHeightInMM = 297;
    var mmPerInch = 25.4;
    var pixels = (sheetHeightInMM * dpi) / mmPerInch;
    var bodyHeight = document.getElementsByTagName('body')[0].scrollHeight;
    console.log(bodyHeight);
    var totalPages = Math.ceil(bodyHeight / pixels);
    console.log(totalPages);
    for (var i = 1; i <= totalPages; i++) {
        var pageNumberLi = document.createElement("li");
        var pageNumber = document.createTextNode("Page " + i + " of " + totalPages);
        pageNumberLi.classList.add('dynamic-page-number');
        pageNumberLi.style.paddingTop = '5px'; // added to adjust spacing between previous li element in dom
        pageNumberLi.style.position = "absolute";
        var offsetTop = document.getElementById("page-number").offsetTop + "px";
        console.log(offsetTop);
        pageNumberLi.style.top = `calc((${i - 1} * ${sheetHeightInMM}mm) + ${offsetTop} - ${i * 1}rem)`;
        pageNumberLi.style.right = '1.5rem'; // 1rem body right margin + 0.5rem header right padding
        pageNumberLi.appendChild(pageNumber);
        document.getElementById("invoice-details").appendChild(pageNumberLi);
    }
}

Expected Behavior:
Page should be generated properly considering the height set in html which is 297mm (height of A4 page).

Please try saving the code snippet as html file and open in browser. The above code snippet execution gives different output.

NodeJS login request hangs indefinitely

I am trying to follow a tutorial on how to set up sessions with express, but am having an issue with getting a response. Whenever I POST to ‘/’ I never get a response and I get no error message. I can POST to register just fine. Not sure what the issue is, help would be appreciated.

app.js

if (process.env.NODE_ENV !== 'production') {
  require('dotenv').config();
}

var createError = require('http-errors');
var express = require('express');
var path = require('path');
//var cookieParser = require('cookie-parser');
var logger = require('morgan');
var mongoose = require("mongoose");
const passport = require("passport");
//const dotenv = require('dotenv').config();
//const dotenv2 = require('dotenv')
const flash = require('express-flash');
const session = require("express-session");
const mongoDb = process.env.MONGODB_URL;
const bcrypt = require("bcrypt");

//imports passport function from file
const initializePassport = require('./passport-config');
initializePassport(passport,
  username => users.find(user => user.username === username),
  id => users.find(user => user.id === id)

);

const users =[];
mongoose.connect(mongoDb, { useUnifiedTopology: true, useNewUrlParser: true });
const db = mongoose.connection;
db.on("error", console.error.bind(console, "mongo connection error"));


var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
const { cookie } = require('express-validator');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

app.use(logger('dev'));
app.use(express.json());


app.use(express.urlencoded({ extended: false }));
app.use(flash())
app.use(session({
  secret: process.env.SESSION_SECRET,
  resave:false,
  saveUninitialized:false
}))
app.use(passport.initialize())
app.use(passport.session());
//app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));



app.use('/', indexRouter);
app.use('/users', usersRouter);


app.get('/', async(req, res, next) => {
  res.render('login.pug');
});

app.post('/', passport.authenticate('local', {
  successRedirect: '/homepage',
  failureRedirect: '/',
  failureFlash:true
}));

app.post("/register", async(req, res) => {
  console.log("Here");
try {
    const hashedPassword = await bcrypt.hash(req.body.password, 10);
    users.push({
      id: Date.now().toString(),
      username: req.body.username,
      password:hashedPassword,
    })
    res.redirect('/');
  } catch {
  res.redirect("/register");
}
console.log(users);
});

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

passport-config.js

const LocalStrategy = require('passport-local').Strategy
const bcrypt = require('bcrypt');


function initialize(passport, getUserByUsername, getUserById) {
    console.log("testing");
    const authenticateUser = async (username, password, done) => {
        const user = getUserByUsername(username);
        if(user == null) {
            return done(null, false, { message:' No user with that name found' });
        }

        try {
            if (await bcrypt.compare(password, user.password)) {
                return done(null,user);
            } else {
                return done(null,false, { message: 'Incorrect password' });
            }
        }
        catch (e){
            return done(e);
        }
    }

    passport.use(new LocalStrategy({username: 'username'},
    authenticateUser));
    passport.serializeUser((user, done) => {null, user.id});
    passport.deserializeUser((id,done) => {return done(null, getUserById(id))});
}

module.exports = initialize;

Connecting my Next js code to Cloud MongoDB

`Error connecting to MongoDB Error: querySrv ENOTFOUND _mongodb._tcp.cluster0.x7daiyv.mongodb.net
at QueryReqWrap.onresolve [as oncomplete] (node:internal/dns/promises:251:17)
at QueryReqWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
errno: undefined,
code: ‘ENOTFOUND’,
syscall: ‘querySrv’,
hostname: ‘_mongodb._tcp.cluster0.x7daiyv.mongodb.net’
}

import mongoose from “mongoose”;
export async function connectMongoDB(){ try { await mongoose.connect(process.env.MONGODB_URI) console.log("Connected to MongoDB"); }catch(err){ if(!process.env.MONGODB_URI){ console.log("Path to MongoDB is not correct"); } console.log("Error connecting to MongoDB",err); throw err; }
}, The MONGODB_URI is correct. i am not understanding where is error and how i fix this. I use chatGPT and Google Bard for this but the error is not fixing. Please can anyone guide me how i fix this error`

‘in ‘ requires string as left operand, not int when trying to make lambda from aws-cli

I am trying to setup github actions to autodeploy lambdas when pushed to main but when i run
aws lambda create-function --function-name "helloWorld" --runtime nodejs20.x --role arn:aws:iam:... --handler "helloWorld.handler" --code fileb://helloWorld.zip
I keep getting the error
'in <string>' requires string as left operand, not int
the zip file just contains helloworld.js
which just has
export const handler = async (event) => { const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!'), }; return response; };

(if it helps the zip file is made using zip -r "helloWorld.zip" ".helloWorld.js")

I tried changing the command to aws lambda create-function --function-name "helloWorld" --runtime nodejs20.x --role arn:aws:iam:... --handler "helloWorld.handler" --code file://helloWorld.zip but that just gave an error of Error parsing parameter '--code': Unable to load paramfile (helloWorld.zip), text contents could not be decoded. If this is a binary file, please use the fileb:// prefix instead of the file:// prefix.