parameter values only being sent to certain columns in google sheet?

I have a web app form with text fields and dropdowns. I am trying to pass certain selections over to a google sheet. I want to bring (in this order): landowner, comments, date, land agent, parcel ID to the corresponding columns in google sheet (columns A-E).

enter image description here

When I press submit, everything but the landowner dropdown sends to the sheet:

enter image description here

Here’s the DoPost and addrecord status I have:

function doPost(e) {
  // Check if the 'e' parameter is defined and contains the expected properties
  if (e && e.parameter) {
    var landowner = e.parameter.landowner ? e.parameter.landowner.toString() : '';
    var substation = e.parameter.substation ? e.parameter.substation.toString() : '';
    var comment = e.parameter.comment ? e.parameter.comment.toString() : '';
    var status = e.parameter.status ? e.parameter.status.toString() : '';
    var supervisor = e.parameter.supervisor ? e.parameter.supervisor.toString() : '';
    var date = e.parameter.date ? e.parameter.date : '';
    var parcelId = e.parameter.parcelId ? e.parameter.parcelId.toString() : ''; // Retrieve parcel ID parameter

    addRecord(landowner, comment, date, supervisor, parcelId); // Pass parcelId to addRecord
    addToStatuses(landowner, status, date, supervisor, parcelId); // Pass parcelId to addToStatuses
    removeDuplicateStatuses();

    var htmlOutput = HtmlService.createTemplateFromFile('DependentSelect');
    var subs = getDistinctSubstations();
    htmlOutput.message = 'Record Added';
    htmlOutput.subs = subs;

    return htmlOutput.evaluate();
  } else {
    // If 'e' parameter is not defined or doesn't contain expected properties, return an error message
    return ContentService.createTextOutput("Error: Invalid request parameters");
  }
}

__

// Function to add a record to the Comments sheet
function addRecord(landowner, comment, date, supervisor, parcelId) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var dataSheet = ss.getSheetByName("Comments");
  var formattedDate = Utilities.formatDate(new Date(date), Session.getScriptTimeZone(), "MM/dd/yy HH:mm");
  dataSheet.appendRow([landowner, comment, formattedDate, supervisor, parcelId]); // Include landowner in column A
}

Can anyone see what I’m missing here?

Run main several times of wasm in browser

I have a C cli program that I compiled to was with Emscripten. I’m trying to run that program each time a button is pressed, and read from a textbox into stdin and from stdout to another textbox. However, I can only call “Module.callMain()” sucessfully once. Each subsequent invocation does not execute. How to properly setup this?

Here is the HTML code.

<!doctype html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>title</title>
  </head>
  <body>
    <textarea id="input" rows="8"></textarea>
    <button onclick="exec()">run</button>
    <textarea id="output" rows="8"></textarea>
    <script>
        var input_box = document.getElementById('input');
        var input_text = "";
        let i = 0;

        var Module = {
            noInitialRun: true,
            noExitRuntime: true,
            print: (function() {
                    var element = document.getElementById('output');
                    if (element) element.value = ''; // clear browser cache
                    return (...args) => {
                        var text = args.join(' ');
                        console.log(text);
                        if (element) {
                        element.value += text + "n";
                        element.scrollTop = element.scrollHeight; // focus on bottom
                        }
                    };
                    })(),
            stdin: (function() {
                    return () => {
                        if(i >= input_text.length) {
                            return null;
                        } else {
                            return input_text.charCodeAt(i++);
                        }
                    };
                    })(),
            };

        function exec() {
            console.log(i);
            i = 0;
            input_text = input_box.value;
            console.log(input_text);

            Module.callMain([]);
        }
    </script>
    <script async type="text/javascript" src="main.js"></script>
  </body>
</html>

The .js file is the one output from emscripten without modifications.
Here are the flags used to compile: -s ‘EXIT_RUNTIME=0′ -s EXPORTED_RUNTIME_METHODS='[“callMain”,”run”]’ -s ENVIRONMENT=web

Folder structure label generation in JavaScript

In my database I have a table called folders.

Each row has an id, name, parent_id

Somehow I’m getting these folder data to a javascript array.

I need to avoid duplications from all and adjust like this,

Imagine if I had folders called Folder 1, Folder 2, Folder 3

Folder 2’s parent is Folder 1, Folder 3’s parent is Folder 2

I need to generate an object like this and set all the objects to an array

{
  label: 'Folder 1 > Folder 2 > Folder 3',
  id: //folder 3 id here
}

How to achieve this kind of in JavaScript. I really appreciate if somebody could help me. Thanks

Function is returning undefined but should be returning a matched object from array in JavaScript

I’m very new to JS. I’m trying to return a matched value from user input from a global array (aStoreItems) for a theoretical online book store. The array consists of objects passed through a constructor.

// Function to find object by ID value

function getBookById(id) {
            console.log("Variable being passed in(in getbookbyid function)= " + id)
            console.log(" type Variable being passed in(ingetbookbyid function)= " + typeof (id))
            for (var i = 0; i < aStoreItems.length; ++i) {
                if (aStoreItems[i].bID == id) {
                    return aStoreItems[i];
                    selectedBook = aStoreItems[i];
                }
            } 
};

// Sample of object in array

var ID23 = new StoreItem("ID23", "The Slow Regard of Silent Things", 12.99, 50, 1, "Fiction", 1.99, ["Great story", 5], "Desc", "<img src='./imgs/the_slow_regard_of_silent_things.jpeg' />");
        

Now I’m trying to implement an add to cart function that passes a user typed value and passes it through the getBookById() function.

Right now I’m just trying to pass the variable created by the users input to find the book that they want to add to cart

function addToCart() {
            var bookSelection = document.getElementById("pID").value;

            console.log("user typed (in add to cart function) " + bookSelection);

            getBookById(bookSelection);
            console.log("return is(in add to cart function) " + selectedBook);
};

console output shows this:
user typed (in add to cart function) ID23
Variable being passed in(in get book by id function)= ID23
type Variable being passed in(in get book by id function)= string
return is(in add to cart function) undefined

I don’t know where I’m going wrong and other solutions researched are not fairing any better

Thanks to all for you help!

Page in React only renders elements after refreshing

Basically I have an authentication application, where I have an authentication page where my user is sent every time the system does not recognize that he is authenticated, authentication occurs when he has a valid token registered in his localstorage with “authorization”, so through “requireAuth” I created a mechanism where when a valid token is not identified in localstorage, the user is sent to the authentication page when he tries to access “/”, and if he is authenticated, then he goes straight to “/ ” and cannot access the auth page. This way

import { useContext } from "react"
import { AuthContext } from "./AuthContext"
import Authpage from "../pages/Authpage";
import { Navigate } from "react-router-dom";

export const RequireAuth = ({ children }: { children: JSX.Element }) => {
    const auth = useContext(AuthContext);

    if (!auth.user) {
      return <Navigate to="/auth" replace />;
    }
    

    return children;
}

As you can see, the “/” page is protected

import { Routes, Route, useNavigate, useLocation } from 'react-router-dom';

import './App.css';
import Homepage from './pages/Homepage';
import Authpage from './pages/Authpage';
import Signuppage from './pages/Signuppage/Signuppage';
import { RequireAuth } from './context/RequireAuth';
import { RequireNotAuth } from './context/RequireNotAuth';
import React from 'react';
import GoogleAuthRedirect from './pages/GoogleAuthRedirect';

export function InvalidRoute() {
  const navigate = useNavigate();
  React.useEffect(() => {
    navigate('/');
  }, [navigate]);

  return null;
}


function App() {
  return (
    <Routes>
      <Route path='/' element={<RequireAuth><Homepage /></RequireAuth>} />
      <Route path='/auth' element={<Authpage />} />
      <Route path='/signup' element={<Signuppage />} />
      <Route path='/googleauth/:id' element={<GoogleAuthRedirect />} />
    </Routes>
  );
}

export default App;

This is the part where my user gets thrown after authentication before being sent to “/”

import * as C from './styles';

import { useNavigate, useParams } from 'react-router-dom';
import { useContext, useEffect, useState } from 'react';
import { useApi } from '../../hooks/useApi';
import { AuthContext } from '../../context/AuthContext';

type Props = {}

const GoogleAuthRedirect = (props: Props) => {
    const { id } = useParams();
    const api = useApi();
    const auth = useContext(AuthContext);
    const navigate = useNavigate();

    const [loading, setLoading] = useState(false);

    useEffect(() => {
        const getToken = async() => {
            try {
                if (id) { 
                    const token = await api.verifyToken(id);
                    setLoading(true);                                   
                    setLoading(false);                                                    

                    if (token.success) {
                        localStorage.setItem('authorization', id);    
                        setLoading(true);                                   
                        setLoading(false);                           
                        navigate('/');
                    }
                } else {
                    console.log("Token não definido.");
                }            
            } catch (err) {
                console.log(err);
            }
        }
        getToken();
    }, []);

  return (
    <div>
        <h3>Autenticando...</h3>
    </div>
  )
}

export default GoogleAuthRedirect;

The problem is that after authenticating and sending the page “/”, nothing is rendered on the page and it is only rendered if I press f5 and refresh the page. Somehow I thought it could be because it is being sent before authenticating in useEffect, so I tried loading it to extend this time and without success.

ps: Homepage

import { useContext, useEffect, useState } from 'react';
import * as C from './styles';
import { useNavigate } from 'react-router-dom';
import { useApi } from '../../hooks/useApi';
import { AuthContext } from '../../context/AuthContext';

type Props = {}

const Homepage = (props: Props) => {
  const navigate = useNavigate();
  const auth = useContext(AuthContext);
  const api = useApi();
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const verifyAuthTK = async () => {
      const authorization = localStorage.getItem('authorization');
      if (authorization) {
        const isAuth = await api.verifyToken(authorization);
        if (isAuth.success) {
          setLoading(false);
        } 
      }
    };
    verifyAuthTK();
  }, []);

  if (loading) {
    return <div>Carregando...</div>;
  }


  return (
    <C.Container>
        homepage
    </C.Container>
  )
}

export default Homepage;

It sends me exactly to the “/” page that I would like, but the problem is that the screen is completely white and I need to press f5 to render the elements and components.

Stop propagation of javasript/leaflet click event that starts in one element and ends in another

I have a Leaflet control that I add to the map using the code below.

...
var FilterControl = L.Control.extend({
    options: {
        position: 'topleft'
    },
  
    onAdd: function(map) {
        this._div = L.DomUtil.create('div', 'leaflet-formcontrol');
        L.DomEvent.disableClickPropagation(this._div);

        return this._div;
    },
  });
...
var filterControl = new FilterControl();
filterControl.addTo(map); 

On the map itself, I bound an event listener:

map.on('click', remove_highlights)

Now, my problem is that when a ‘click’ event is started (mousedown) in the control layer, but ends on the map (on mouseup) after dragging the mouse, the click event of the map is triggered, which I do not want. The situation occurs quite easily because there is a slider on the controllayer.

Mozilla describes the behaviour, but it does not become clear to me how to solve it. For instance, stopPropagation() or stopImmediatePropagation() does not work, not on the map or on the layercontrol, when adding a click event listener to it. Also, setting L.DomEvent.disableClickPropagation(..) but then on the map element, does not work.

Does anyone have any experience with this problem?

Best, Robert

With non-graphical maps in Leaflet, zoomDelta doesn’t work

I want to subdivde the number of scrolling wheels it takes to reach max zoom.. but zoomDelta not working. No matter what zoomDelta value is, it zooms by 1 always.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Custom Zoom Control</title>
    <!-- Include Leaflet CSS -->
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
    <!-- Include Leaflet JavaScript -->
    <script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
</head>
<body>
    <!-- Create a div element with ID 'map' to contain the map -->
    <div id="map" style="width: 600px; height: 400px;"></div>

    <script>
        // Initialize the map with a center, zoom level, and other options
        var map = L.map('map', {
            center: [500, 500], // Initial center latitude and longitude
            zoom: 1, // Initial zoom level
            minZoom: 1, // Minimum zoom level
            maxZoom: 3, // Maximum zoom level
            crs: L.CRS.Simple // Use Simple CRS for image overlay
        });

        // Define bounds for the image overlay
        var bounds = [[0,0], [1000,1000]];

        // Add an image overlay using your image
        var image = L.imageOverlay('Texture/test map.png', bounds).addTo(map);

        // Remove the default zoom control
        map.zoomControl.remove();

        // Add event listener for zoomstart event
        map.on('zoom', function(event) {
            console.log('Current Zoom Level: ' + map.getZoom());
        });
    </script>
</body>
</html>

Console log:

Current Zoom Level: 2 Text6.html:37
Current Zoom Level: 3 Text6.html:37
Current Zoom Level: 2 Text6.html:37
Current Zoom Level: 1 Text6.html:37

Problems with matter.js and i18n in vue.js

In this code, the language change is made when I reload the page, so I would like a solution so that it happens instantly and I don’t have to reload the page.

<template>
  <div ref="scene" class="scene"></div>
</template>

<script>
import { onMounted, ref } from "vue";
import Matter from "matter-js";
import { useI18n } from "vue-i18n";

export default {
  setup() {
    const scene = ref(null);
    const balls = ref([]);
    const { t } = useI18n();

    onMounted(() => {
      const engine = Matter.Engine.create({ gravity: { x: 0, y: 0.3 } });

      const render = Matter.Render.create({
        element: scene.value,
        engine: engine,
        options: {
          width: window.innerWidth / 5,
          height: window.innerHeight / 2,
          wireframes: false,
          background: "transparent",
        },
      });

      Matter.Render.run(render);

      const createPhysicalButton = (key) => {
        const buttonWidth = 165;
        const buttonHeight = 45;
        const cornerRadius = 20;

        const x =
            Math.random() * (window.innerWidth / 8 - buttonWidth * 2 - 100) +
            buttonWidth +
            50;
        const y =
            Math.random() * (window.innerHeight / 2 - buttonHeight * 2 - 100) +
            buttonHeight +
            50;
        const angle = Math.random() * Math.PI * 2;

        const body = Matter.Bodies.rectangle(x, y, buttonWidth, buttonHeight, {
          chamfer: { radius: cornerRadius },
          angle: angle,
          isStatic: false,
          restitution: 0.4,
          frictionAir: 0.004,
          density: 0.01,
          render: { visible: false },
        });
        body.initialPosition = { x, y };

        const button = document.createElement("button");
        button.innerText = t(key);
        button.style.padding = "10px";
        button.style.borderRadius = `${cornerRadius}px`;
        button.style.border = "1px solid #333";
        button.style.backgroundColor = "transparent";
        button.style.position = "absolute";
        button.style.left = `${x - buttonWidth / 2}px`;
        button.style.top = `${y - buttonHeight / 2}px`;
        button.style.width = `${buttonWidth}px`;
        button.style.height = `${buttonHeight}px`;
        scene.value.appendChild(button);

        const limiterVitesse = (corps, vitesseMax) => {
          const vitesse = Matter.Vector.magnitude(corps.velocity);
          if (vitesse > vitesseMax) {
            Matter.Body.setVelocity(
                corps,
                Matter.Vector.mult(
                    Matter.Vector.normalise(corps.velocity),
                    vitesseMax
                )
            );
          }
        };

        Matter.Events.on(engine, "afterUpdate", () => {
          button.style.left = `${body.position.x - buttonWidth / 2}px`;
          button.style.top = `${body.position.y - buttonHeight / 2}px`;
          button.style.transform = `rotate(${body.angle}rad)`;
          [...balls.value, ...buttons].forEach((corps) =>
              limiterVitesse(corps, 10)
          );

          const maxSpeed = 10;
          const speed = Matter.Vector.magnitude(body.velocity);
          if (speed > maxSpeed) {
            Matter.Body.setVelocity(
                body,
                Matter.Vector.mult(
                    Matter.Vector.normalise(body.velocity),
                    maxSpeed
                )
            );
          }
        });

        return body;
      };

      const buttons = [
        createPhysicalButton("button.fun"),
        createPhysicalButton("button.awareness"),
        createPhysicalButton("button.act"),
        createPhysicalButton("button.enjoy"),
        createPhysicalButton("button.learn"),
        createPhysicalButton("button.ecology"),
        createPhysicalButton("button.education"),
      ];

      Matter.World.add(engine.world, buttons);

      const colors = ["#551126", "#C1DD13", "#ABCDFF"];

      const createBall = (color) => {
        const ballSize = 6;
        const x =
            Math.random() * (window.innerWidth / 8 - ballSize * 2 - 100) +
            ballSize +
            50;
        const y =
            Math.random() * (window.innerHeight / 2 - ballSize * 2 - 100) +
            ballSize +
            50;
        const angle = Math.random() * Math.PI * 2;

        const ball = Matter.Bodies.circle(x, y, ballSize, {
          angle: angle,
          isStatic: false,
          restitution: 0.4,
          frictionAir: 0.004,
          density: 0.01,
          render: {
            fillStyle: color,
            strokeStyle: "transparent",
          },
        });

        balls.value.push(ball);
        Matter.World.add(engine.world, ball);

        return ball;
      };

      const createdBalls = colors.map((color) => createBall(color));

      Matter.World.add(engine.world, createdBalls);

      const wallOptions = {
        isStatic: true,
        render: { visible: false },
      };

      const wallThickness = 200; // Augmentez l'épaisseur des murs pour empêcher le passage des balles

      // Assurez-vous que la position et la taille des murs couvrent correctement les bords de la scène
      const leftWall = Matter.Bodies.rectangle(-wallThickness / 2, window.innerHeight / 4, wallThickness, window.innerHeight * 2, wallOptions);
      const rightWall = Matter.Bodies.rectangle(window.innerWidth / 5 + wallThickness / 2, window.innerHeight / 4, wallThickness, window.innerHeight * 2, wallOptions);

      const topWall = Matter.Bodies.rectangle(
          window.innerWidth / 16,
          -wallThickness / 2,
          window.innerWidth * 2,
          wallThickness,
          wallOptions
      );
      const bottomWall = Matter.Bodies.rectangle(
          window.innerWidth / 16,
          window.innerHeight / 2 + wallThickness / 2,
          window.innerWidth * 2,
          wallThickness,
          wallOptions
      );

      Matter.World.add(engine.world, [
        leftWall,
        rightWall,
        topWall,
        bottomWall,
      ]);

      Matter.Events.on(engine, "collisionStart", (event) => {
        event.pairs.forEach((pair) => {
          const { bodyA, bodyB } = pair;

          if (
              balls.value.includes(bodyA) &&
              (leftWall === bodyB ||
                  rightWall === bodyB ||
                  topWall === bodyB ||
                  bottomWall === bodyB)
          ) {
            Matter.Body.setVelocity(bodyA, {
              x: -bodyA.velocity.x * 0.5,
              y: -bodyA.velocity.y * 0.5,
            });
          }

          if (
              balls.value.includes(bodyB) &&
              (leftWall === bodyA ||
                  rightWall === bodyA ||
                  topWall === bodyA ||
                  bottomWall === bodyA)
          ) {
            Matter.Body.setVelocity(bodyB, {
              x: -bodyB.velocity.x * 0.5,
              y: -bodyB.velocity.y * 0.5,
            });
          }
        });
      });

      let lastMousePosition = { x: 0, y: 0 };

      window.addEventListener("mousemove", (event) => {
        const sceneRect = scene.value.getBoundingClientRect();
        const mousePosition = {
          x: event.clientX - sceneRect.left,
          y: event.clientY - sceneRect.top,
        };
        const mouseVelocity = {
          x: mousePosition.x - lastMousePosition.x,
          y: mousePosition.y - lastMousePosition.y,
        };

        buttons.forEach((button) => {
          const distance = Matter.Vector.magnitude(
              Matter.Vector.sub(button.position, mousePosition)
          );
          if (distance < 50 && Matter.Vector.magnitude(mouseVelocity) > 0) {
            const maxMouseSpeed = 20;
            const buttonSpeed = Matter.Vector.magnitude(mouseVelocity);
            if (buttonSpeed > maxMouseSpeed) {
              Matter.Body.setVelocity(
                  button,
                  Matter.Vector.mult(
                      Matter.Vector.normalise(mouseVelocity),
                      maxMouseSpeed
                  )
              );
            } else {
              Matter.Body.setVelocity(button, mouseVelocity);
            }
          }
        });

        balls.value.forEach((ball) => {
          const distance = Matter.Vector.magnitude(
              Matter.Vector.sub(ball.position, mousePosition)
          );
          if (distance < 50 && Matter.Vector.magnitude(mouseVelocity) > 0) {
            const maxMouseSpeed = 20;
            const ballSpeed = Matter.Vector.magnitude(mouseVelocity);
            if (ballSpeed > maxMouseSpeed) {
              Matter.Body.setVelocity(
                  ball,
                  Matter.Vector.mult(
                      Matter.Vector.normalise(mouseVelocity),
                      maxMouseSpeed
                  )
              );
            } else {
              Matter.Body.setVelocity(ball, mouseVelocity);
            }
          }
        });

        lastMousePosition = mousePosition;
      });

      const runner = Matter.Runner.create();
      Matter.Runner.run(runner, engine);
    });

    return { scene };
  },
};
</script>

<style>
.scene {
  width: 50vw;
  height: 30vh;
  position: absolute; /* ou 'relative' selon le besoin */
  top: 60%;
  left: 73%;
  transform: translate(-50%, -50%);
  margin-top: 100px;
}

button {
  z-index: 10;
  border-radius: 20px;
  border: 1px solid #333;
  background-color: transparent;
  transform-origin: center center;
  cursor: auto;
}

</style>

In this case, I don’t need to reload the page, but the buttons are no longer subject to the same reactivity as before.

<template>
  <div ref="scene" class="scene"></div>
</template>

<script>
import { onMounted, ref, watch } from "vue";
import Matter from "matter-js";
import { useI18n } from "vue-i18n";

export default {
  setup() {
    const scene = ref(null);
    const balls = ref([]);
    const buttons = ref([]);
    const { t, locale } = useI18n();

    const updatePhysicalButtons = () => {
      if (!scene.value) {
        console.warn("Scene not ready.");
        return;
      }

      const existingButtons = scene.value.querySelectorAll('button');
      existingButtons.forEach(button => button.remove());

      const buttonKeys = [
        "button.fun",
        "button.awareness",
        "button.act",
        "button.enjoy",
        "button.learn",
        "button.ecology",
        "button.education",
      ];
      buttonKeys.forEach(key => createPhysicalButton(key));
    };

    const createPhysicalButton = (key) => {
      const buttonWidth = 165;
      const buttonHeight = 45;
      const cornerRadius = 20;

      const x =
          Math.random() * (window.innerWidth / 8 - buttonWidth * 2 - 100) +
          buttonWidth +
          50;
      const y =
          Math.random() * (window.innerHeight / 2 - buttonHeight * 2 - 100) +
          buttonHeight +
          50;
      const angle = Math.random() * Math.PI * 2;

      const body = Matter.Bodies.rectangle(x, y, buttonWidth, buttonHeight, {
        chamfer: { radius: cornerRadius },
        angle: angle,
        isStatic: false,
        restitution: 0.4,
        frictionAir: 0.004,
        density: 0.01,
        render: { visible: false },
      });
      body.initialPosition = { x, y };

      const button = document.createElement("button");
      button.innerText = t(key);
      button.style.padding = "10px";
      button.style.borderRadius = `${cornerRadius}px`;
      button.style.border = "1px solid #333";
      button.style.backgroundColor = "transparent";
      button.style.position = "absolute";
      button.style.left = `${x - buttonWidth / 2}px`;
      button.style.top = `${y - buttonHeight / 2}px`;
      button.style.width = `${buttonWidth}px`;
      button.style.height = `${buttonHeight}px`;
      scene.value.appendChild(button);

      const limiterVitesse = (corps, vitesseMax) => {
        const vitesse = Matter.Vector.magnitude(corps.velocity);
        if (vitesse > vitesseMax) {
          Matter.Body.setVelocity(
              corps,
              Matter.Vector.mult(
                  Matter.Vector.normalise(corps.velocity),
                  vitesseMax
              )
          );
        }
      };

      Matter.Events.on(engine, "afterUpdate", () => {
        button.style.left = `${body.position.x - buttonWidth / 2}px`;
        button.style.top = `${body.position.y - buttonHeight / 2}px`;
        button.style.transform = `rotate(${body.angle}rad)`;
        [...balls.value, ...buttons.value].forEach((corps) =>
            limiterVitesse(corps, 10)
        );

        const maxSpeed = 10;
        const speed = Matter.Vector.magnitude(body.velocity);
        if (speed > maxSpeed) {
          Matter.Body.setVelocity(
              body,
              Matter.Vector.mult(
                  Matter.Vector.normalise(body.velocity),
                  maxSpeed
              )
          );
        }
      });

      buttons.value.push(body);

      return body;
    };

    let engine;

    onMounted(() => {
      engine = Matter.Engine.create({ gravity: { x: 0, y: 0.3 } });
      const render = Matter.Render.create({
        element: scene.value,
        engine: engine,
        options: {
          width: window.innerWidth / 5,
          height: window.innerHeight / 2,
          wireframes: false,
          background: "transparent",
        },
      });

      Matter.Render.run(render);
      updatePhysicalButtons();

      const colors = ["#551126", "#C1DD13", "#ABCDFF"];

      const createBall = (color) => {
        const ballSize = 6;
        const x =
            Math.random() * (window.innerWidth / 8 - ballSize * 2 - 100) +
            ballSize +
            50;
        const y =
            Math.random() * (window.innerHeight / 2 - ballSize * 2 - 100) +
            ballSize +
            50;
        const angle = Math.random() * Math.PI * 2;

        const ball = Matter.Bodies.circle(x, y, ballSize, {
          angle: angle,
          isStatic: false,
          restitution: 0.4,
          frictionAir: 0.004,
          density: 0.01,
          render: {
            fillStyle: color,
            strokeStyle: "transparent",
          },
        });

        balls.value.push(ball);
        Matter.World.add(engine.world, ball);

        return ball;
      };

      const createdBalls = colors.map((color) => createBall(color));

      Matter.World.add(engine.world, createdBalls);

      const wallOptions = {
        isStatic: true,
        render: { visible: false },
      };

      const wallThickness = 200;

      const leftWall = Matter.Bodies.rectangle(-wallThickness / 2, window.innerHeight / 4, wallThickness, window.innerHeight * 2, wallOptions);
      const rightWall = Matter.Bodies.rectangle(window.innerWidth / 5 + wallThickness / 2, window.innerHeight / 4, wallThickness, window.innerHeight * 2, wallOptions);

      const topWall = Matter.Bodies.rectangle(
          window.innerWidth / 16,
          -wallThickness / 2,
          window.innerWidth * 2,
          wallThickness,
          wallOptions
      );
      const bottomWall = Matter.Bodies.rectangle(
          window.innerWidth / 16,
          window.innerHeight / 2 + wallThickness / 2,
          window.innerWidth * 2,
          wallThickness,
          wallOptions
      );

      Matter.World.add(engine.world, [
        leftWall,
        rightWall,
        topWall,
        bottomWall,
      ]);

      Matter.Events.on(engine, "collisionStart", (event) => {
        event.pairs.forEach((pair) => {
          const { bodyA, bodyB } = pair;

          if (
              balls.value.includes(bodyA) &&
              (leftWall === bodyB ||
                  rightWall === bodyB ||
                  topWall === bodyB ||
                  bottomWall === bodyB)
          ) {
            Matter.Body.setVelocity(bodyA, {
              x: -bodyA.velocity.x * 0.5,
              y: -bodyA.velocity.y * 0.5,
            });
          }

          if (
              balls.value.includes(bodyB) &&
              (leftWall === bodyA ||
                  rightWall === bodyA ||
                  topWall === bodyA ||
                  bottomWall === bodyA)
          ) {
            Matter.Body.setVelocity(bodyB, {
              x: -bodyB.velocity.x * 0.5,
              y: -bodyB.velocity.y * 0.5,
            });
          }
        });
      });

      let lastMousePosition = { x: 0, y: 0 };

      window.addEventListener("mousemove", (event) => {
        const sceneRect = scene.value.getBoundingClientRect();
        const mousePosition = {
          x: event.clientX - sceneRect.left,
          y: event.clientY - sceneRect.top,
        };
        const mouseVelocity = {
          x: mousePosition.x - lastMousePosition.x,
          y: mousePosition.y - lastMousePosition.y,
        };

        buttons.value.forEach((button) => {
          const distance = Matter.Vector.magnitude(
              Matter.Vector.sub(button.position, mousePosition)
          );
          if (distance < 50 && Matter.Vector.magnitude(mouseVelocity) > 0) {
            const maxMouseSpeed = 20;
            const buttonSpeed = Matter.Vector.magnitude(mouseVelocity);
            if (buttonSpeed > maxMouseSpeed) {
              Matter.Body.setVelocity(
                  button,
                  Matter.Vector.mult(
                      Matter.Vector.normalise(mouseVelocity),
                      maxMouseSpeed
                  )
              );
            } else {
              Matter.Body.setVelocity(button, mouseVelocity);
            }
          }
        });

        balls.value.forEach((ball) => {
          const distance = Matter.Vector.magnitude(
              Matter.Vector.sub(ball.position, mousePosition)
          );
          if (distance < 50 && Matter.Vector.magnitude(mouseVelocity) > 0) {
            const maxMouseSpeed = 20;
            const ballSpeed = Matter.Vector.magnitude(mouseVelocity);
            if (ballSpeed > maxMouseSpeed) {
              Matter.Body.setVelocity(
                  ball,
                  Matter.Vector.mult(
                      Matter.Vector.normalise(mouseVelocity),
                      maxMouseSpeed
                  )
              );
            } else {
              Matter.Body.setVelocity(ball, mouseVelocity);
            }
          }
        });

        lastMousePosition = mousePosition;
      });

      const runner = Matter.Runner.create();
      Matter.Runner.run(runner, engine);
    });

    watch(locale, () => {
      updatePhysicalButtons();
    }, { immediate: true });

    return { scene };
  },
};
</script>

<style>
.scene {
  width: 50vw;
  height: 30vh;
  position: absolute;
  top: 60%;
  left: 73%;
  transform: translate(-50%, -50%);
  margin-top: 100px;
}

button {
  z-index: 10;
  border-radius: 20px;
  border: 1px solid #333;
  background-color: transparent;
  transform-origin: center center;
  cursor: auto;
}
</style>

So I tried the things said above

On the server side, it returns undefined but on the client side, logs the values no problem

I’ve been searching for days now but cannot find what’s wrong. I’m trying to update a user after creating a username and password.
Backend updating user

app.put('/users/:userId', async (req, res) => {
    const client = new MongoClient(uri)
    const formData = req.body;

    try {
        await client.connect();
        const database = client.db('app-data')
        const users = database.collection('users');
        console.log("Form data", formData);
        const query = {user_id: formData.userId}
        const updateDocument = {
            $set: {
                first_name: formData?.first_name,
                last_name: formData?.last_name,
                birthdate: formData?.birthdate,
                birth_month: formData?.birth_month,
                birth_year: formData?.birth_year,
                gender: formData?.gender,
                major: formData?.major,
                cleanliness: formData?.cleanliness,
                bio: formData?.bio
            },
        }
        const insertedUser = await users.updateOne(query, updateDocument);
        return res.json(insertedUser);

Frontend form submission

import { useState } from "react";
import { useNavigate } from "react-router-dom";
import axios from "axios";
import React from "react";

const Survey = () => {
    const [formData, setFormData] = useState({
        first_name: '',
        last_name: '',
        birthdate: '',
        birth_month: '',
        birth_year: '',
        gender: '',
        class_rank: '',
        major: '',
        cleanliness: '',
        major_interest: '',
        bio: ''
    })

const navigate = useNavigate();

const handleSubmit = async (e) => {
        e.preventDefault();
        try {
            console.log("Form data: ", formData);
            const userId = localStorage.getItem('userId');
            const response = await axios.put(`http://localhost:8000/users/${userId}`, formData);
     
            navigate('/feed');

            return response;
            
        } catch(err) {
            console.log(err);
        }
    }

    const handleChange = (e) => {
        const value = e.target.value
        const name = e.target.name
        console.log("Updating:", {[name]: value})

        setFormData((prevState) => ({
            ...prevState,
            [name]: value
        }))
    }
    return (
       // HTML form for above values 
)

I’m wanting it update user with these entries in the database but it does not on console logging the form data, it gives.

Form data undefined
{
  acknowledged: true,
  modifiedCount: 0,
  upsertedId: null,
  upsertedCount: 0,
  matchedCount: 0
}

At this point, that is the only error message. I’ve tried getting the item from local storage on the server side, setting as cookies, and some other suggestions I’m unsure of.

AppScript to replace image in google slides

I’m trying to write a gsheet appscript that replaces an image in google slide. Ultimately, i want to iterate through the spreadsheet and for each row create a new slide with the image of the row in the spreadsheet. Currently, I can’t get it to work once.

My code is below:

function updatePresentation() {
  // Replace with your actual presentation ID
  const PRESENTATION_ID = "My_ID"
  // Get the spreadsheet object
  const sheet = SpreadsheetApp.getActiveSheet();
  // Get data range (excluding header row)
  const dataRange = sheet.getDataRange().getValues().slice(1);
  
  // Access the Slides service
  const slidesApp = SlidesApp.openById(PRESENTATION_ID);
  
  // Get the template slide
  const templateSlide = slidesApp.getSlides()[0];
  const pageElements = templateSlide.getPageElements();
  Logger.log(pageElements)

  imageName = "test01.png"
  const imageBlob = DriveApp.getFilesByName(imageName).next().getBlob();

  const left = 0;   // The x-coordinate of the top left corner of the image
  const top = 0;    // The y-coordinate of the top left corner of the image
  const width = 200; // Width of the image
  const height = 100; // Height of the image
  
  // Add the image to the slide
  Logger.log(templateSlide.insertImage(imageBlob, left, top, width, height));

}

The current error message is
” Exception: The image you are trying to use is invalid or corrupt.”

I’ve tried this a number of different ways with no success. Any help would be appreciated.

Ns biding abording issue only on Firefox

I have a problem in the Firefox browser that I cannot solve. So the problem is the following: I have a function that I use to collect data when a page receives a refresh

const eventName = isOnIOS ? "pagehide" : "beforeunload";
        
this.window.addEventListener(eventName, async () => {
  await this.saveAction(this.typeOfActions.unknown);
  await this.saveActionMetaData();
});
saveAction = async (
        type, 
        filters = null, 
        searchTerm = "",
        url = null
        ) => {
        await this.http.post(`${this.collectorApi}${this.endpoints.action}`, {
            target: url ? url : this.currentUrl,
            duration: Math.round((this.timeSpentOnPage / 1000) * 100) / 100 || 0,
            idle_time: isNaN(this.idleTime) ? 0 : Math.round((this.idleTime / 1000) * 100) / 100,
            type: type,
            filters: ! filters ? {} : filters,
            session_id: this.#getSessionId(),
            searched_term: searchTerm
        });
    }
saveActionMetaData = async () => {
        await this.http.post(`${this.collectorApi}${this.endpoints.actionMetaData}`, {
            filters: [],
            data: {},
            idle_time: Math.round((this.timeSpentOnPage / 1000) * 100) / 100 || 0,
            duration: isNaN(this.idleTime) ? 0 : Math.round((this.idleTime / 1000) * 100) / 100,
            action_url: this.currentUrl,
            search_terms: [],
            session_id: this.#getSessionId()
        });
    }

post = async (
        endpoint, 
        data
    ) => {
        try {
            return await (await fetch(endpoint, {
                method: "POST",
                headers: this.headers,
                body: JSON.stringify(data)
            })).json();
        } catch (e) {
            console.error(e);
        }
    }

I can’t figure out where the error is. I simply get that error only on Firefox.

why promise returns an unexpected output for nested promises?

I have code below and based on MDN document, I know how result and state will be specified for a promise, resulted from a handler:

returns a value: p gets fulfilled with the returned value as its
value.

doesn’t return anything: p gets fulfilled with undefined as its
value.

throws an error: p gets rejected with the thrown error as its
value.

returns an already fulfilled promise: p gets fulfilled with
that promise’s value as its value.

returns an already rejected promise: p gets rejected with that promise’s > value as its value.

returns another pending promise: p is pending and becomes
fulfilled/rejected with that promise’s value as its value immediately
after that promise becomes fulfilled/rejected.

so why the state for my promise is fullfilled?

code:

const test = Promise.reject(new Promise((resolve, reject) => {
throw new Error("error")
}))

const test2 = test.catch((result) => {
result.catch(() => {
    throw new Error("error2");
})
})

console.log(test2);

//result in console:
//[[Prototype]]: Promise
//[[PromiseState]]: "fulfilled"
//[[PromiseResult]]: undefined

Callback and Microtask Queue of Java Script

p1 = new Promise((res,rej)=>{
    console.log("p1 setTimeout");
    setTimeout(()=>{
      res(17);
    }, 10000);
});

p2 = new Promise((res,rej)=>{
    console.log("p2 setTimeout");
    setTimeout(()=>{
      res(36);
    }, 2000);
});

function checkIt() {
    console.log("Started");

    let val1 = this.p1;
    console.log("P1");
    val1.then((data)=>{console.log("P1 => "+data)});

    let val2 = this.p2;
    console.log("P2");
    val2.then((data)=>{console.log("P2 => "+data)});

    console.log("End");
}

checkIt();

My understanding of above written JavaScript code was:

1: In callback queue, p2’s setTimeout will be first and then p1’s setTimeout (and they will execute in FIFO manner)

2: Callback queue won’t execute before microtask queue

3: In microtask queue, p1’s callback function will first and then p2’s callback function (and they will execute in FIFO manner)

4: Hence this should be deadlock.

But instead getting output:

1: p1 setTimeout

2: p2 setTimeout

3: Started

4: P1

5: P2

6: End

7: (After 2 seconds) P2 => 36

8: (After 10 seconds) P1 => 17

Doubt: How 7th and 8th line of output are coming?

I have ran the code and getting output as defined above

Authenticating vue app on each route change

More of a general question more than anything. I am authenticating during login and storing the token jwt response in local storage and on each route change running checkLogin which checks the token is valid by hitting /token/validate. Im doing this asynchronously for unprotected pages to help with performance and requiring it for protected pages before proceeding. Im doing the same process for grabbing fresh user data for if user data has been updated in the mean time.

My question is do i need to validate each route change as theyve authenticated on login and each page has many protected REST endpoints that check against the token anyway so if any of those come back invalid i can force logout there instead. Trying to speed things up as on each route change its quite slow as it performs these lookups before getting any endpoint data for data on the page. Also for any endpoints that are quite data heavy is it worth prefetching those after login so when you visit the route it already has that data?

async handleRouteChange(newRoute, oldRoute) {

      if (newRoute.path === '/edit-profile') {
        await this.checkLogin();
      } else {
        this.checkLogin();
      }
    
      if(this.$store.state.user_data){
        this.updateUserData();
      }else{
        await this.updateUserData();
      }

},