How to get “Results per Row” (from a ‘clicked entry’ off a “dropdown menu”) to show up correctly?

Coding Hobbyist here trying to figure out how to: “Create a Digital Archive.”

more specifically:

A.) “when someone stumbles upon this (HTML/CSS/JavaScript only) webpage, they’ll see a list of items (that, when their mouse hovers over such an item, such an item zooms in).

B.) The list of items they’ll see, will be either:
3 entries per row,
5 entries per row,
or 10 entries per row. (almost like, you’re looking through someone’s archive of artwork. (a random passerbyer, can click from the dropdown menu, if they wanna see “3,5,or 10” images at a time (that’s the code we’re working on together today.).

C.) I have coded together something that shows 3 entries per row.

C.1) I’m stuck. i do not know what’s the best method/code/ability to move forward. Like:

C.1.1) If a random person comes to my webpage, and wants to see “5 entries per row.” How do i get “image number 4” to show up after the third entry? but then BOUNCE BACK TO THE NEXT ROW, if someone chooses “theyd rather see 3 entries per row.”

Here is my provided code before i continue further:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Digital Archive 3-5-10 Images Per Row</title>
<style>
.CenterOfCardCreationPage {
text-align: center;
}
.ContainerForCardCreationContainer {
flex-direction: column;
}
.CardCreationContainer {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: flex-start; 
padding: 20px;
}
.CardCreationColumn {
flex: 0 0 30%; 
margin: 10px;
padding: 10px;
text-align: center;
}
.CardCreationButton {
display: inline-block;
padding: 10px 20px;
color: white;
text-decoration: none;
border: none;
cursor: pointer;
}
.CardCreationImage {
width: 100%;
height: auto;
object-fit: contain;
}
@media (max-width: 600px) {
.CardCreationColumn {
flex: 0 0 45%;
}
}
@media (max-width: 400px) {
.CardCreationColumn {
flex: 0 0 90%;
}
}
</style>
</head>
<body>
<header class="CenterOfCardCreationPage">
<h1>Items Per Page: 3,5 or 10?</h1>
<label for="resultsPerPage">How many Results would you like?</label>
<select id="resultsPerPage">
<option value="1">3</option>
<option value="2">5</option>
<option value="3">10</option>
</select>
</header>
<div class="ContainerForCardCreationContainer">
<div class="CardCreationContainer">
<div class="CardCreationColumn">
<button id="uploadButton1" onclick="uploadImage(1)">Upload Image</button>
<div id="imagePlaceholder1" class="CardCreationButton">
<img id="image1" class="CardCreationImage" src="" alt="An Image 01" />
</div>
</div>
<div class="CardCreationColumn">
<button id="uploadButton2" onclick="uploadImage(2)">Upload Image</button>
<div id="imagePlaceholder2" class="CardCreationButton">
<img id="image2" class="CardCreationImage" src="" alt="An Image 02" />
</div>
</div>
<div class="CardCreationColumn">
<button id="uploadButton3" onclick="uploadImage(3)">Upload Image</button>
<div id="imagePlaceholder3" class="CardCreationButton">
<img id="image3" class="CardCreationImage" src="" alt="An Image 03" />
</div>
</div>
</div>
<div class="CardCreationContainer">
<div class="CardCreationColumn">
<button id="uploadButton4" onclick="uploadImage(4)">Upload Image</button>
<div id="imagePlaceholder4" class="CardCreationButton">
<img id="image4" class="CardCreationImage" src="" alt="An Image 04" />
</div>
</div>
<div class="CardCreationColumn">
<button id="uploadButton5" onclick="uploadImage(5)">Upload Image</button>
<div id="imagePlaceholder5" class="CardCreationButton">
<img id="image5" class="CardCreationImage" src="" alt="An Image 05" />
</div>
</div>
<div class="CardCreationColumn">
<button id="uploadButton6" onclick="uploadImage(6)">Upload Image</button>
<div id="imagePlaceholder6" class="CardCreationButton">
<img id="image6" class="CardCreationImage" src="" alt="An Image 06" />
</div>
</div>
</div>
<div class="CardCreationContainer">
<div class="CardCreationColumn">
<button id="uploadButton7" onclick="uploadImage(7)">Upload Image</button>
<div id="imagePlaceholder7" class="CardCreationButton">
<img id="image7" class="CardCreationImage" src="" alt="An Image 74" />
</div>
</div>
<div class="CardCreationColumn">
<button id="uploadButton8" onclick="uploadImage(8)">Upload Image</button>
<div id="imagePlaceholder8" class="CardCreationButton">
<img id="image8" class="CardCreationImage" src="" alt="An Image 08" />
</div>
</div>
<div class="CardCreationColumn">
<button id="uploadButton9" onclick="uploadImage(9)">Upload Image</button>
<div id="imagePlaceholder9" class="CardCreationButton">
<img id="image9" class="CardCreationImage" src="" alt="An Image 09" />
</div>
</div>
</div>
</div>
<!-- Footer with centered text -->
<footer class="CenterOfCardCreationPage">
<h2>Thank you for checking this code out!</h2>
</footer>
<script>
//the code below is the stuff for dropdownmenu
const resultsPerPageSelect = document.getElementById('resultsPerPage');
const cardCreationContainers = document.getElementsByClassName('CardCreationContainer');
resultsPerPageSelect.addEventListener('change', (event) => {
const selectedOption = parseInt(event.target.value, 10);
for (let i = 0; i < cardCreationContainers.length; i++) {
if (i < selectedOption) {
cardCreationContainers[i].style.display = 'flex';
} else {
cardCreationContainers[i].style.display = 'none';
}
}
});
// Initial display based on the selected option
resultsPerPageSelect.dispatchEvent(new Event('change'));
// the stuff below is the code for uploading images
let uploadedImages = 0;
// Function to handle image upload
function uploadImage(CardCreationColumnNumber) {
const input = document.createElement('input');
input.type = 'file';
input.accept = 'image/*';
input.onchange = function () {
const file = this.files[0];
const reader = new FileReader();

reader.onload = function () {
const imagePlaceholder = document.getElementById(`image${CardCreationColumnNumber}`);
imagePlaceholder.src = reader.result;
uploadedImages++;
// Enable the second button if the first image is uploaded 
if (CardCreationColumnNumber === 1) {
const secondButton = document.getElementById('uploadButton27');
secondButton.disabled = false;
}
};
reader.readAsDataURL(file);
};
input.click();
}
</script>
</body>
</html>

C.1.2.) Like, what i tried was plugging in the “fourth and fifth image” (and then the 6th to 10th) into the first row, (and such equivalents in the second two rows) but that didnt work. when someone would change from 5 rows back to 3, or 10 rows back to 3, those “IDs, that represented other images, would disappear from view, and only the next visible set of rows would show their IDs”.

D.) Which leads to my question, (for I think I’m seeing this too much from one point of view and not wanting to abandon it cause I worked on it for a hot minute). “How do i properly fix/upgrade this so that when a random passerbyer sees this webpage, they can choose if they want to see 3, 5, 10 results/images per ROW, and if and when they ever wish to change it back to 3 images per ROW, we dont lose image number 4-10 in the first row just for the second row to show its first 3 options (which would have been image 11, 12, 13 (and then the third row showing images 21, 22, & 23) instead of just “image 4,5,6 being removed from the first row, and being placed in the second row; and image 7 8 and 9 being placed in third row.”

(Note: Semi-unrelated-note about this question: I think i kept saying: “Results per page” when i meant “Results per row” i edited it here and there but if i missed any- my b- but thats what i mean here. Results per page would be cool but not the goal right now.)

Y’all get what I be asking? I’m stuck on how to move forward; any help (or even any sage advice on how to better tackle this on) would be greatly appreciated!

-Scholah

React Native FlatList onScroll Becomes Unresponsive with Large Data Sets in Expo App

I’m working on an Expo React Native app that has a header, footer, and an action button toggle that animates based on the scroll direction. The app has two tabs on the home page: “Social Posts” and “Rankings”. The “Social Posts” tab displays dynamic content loaded from an API, while the “Rankings” tab is static.

The issue I’m facing is with the “Social Posts” tab, which uses a FlatList to display a large amount of data. When the list reaches the end, it loads more data using onEndReached. The header, footer, and button animate out of view when scrolling down, which is working as expected. However, as the data grows larger, the onScroll event in the FlatList becomes unresponsive and does not fire consistently.

This inconsistency causes the header, footer, and button to get stuck in their last state and stop responding to scroll events. I’ve tried various performance optimizations, including using useMemo and useCallback on each list item, but the problem persists. The scroll experience becomes laggy and feels less smooth when there’s a large dataset.

Demo:

I’ve created a Snack demo that replicates the issue. You can find the complete code and see the problem in action by visiting the demo.

Here is a simplified version of my code:

import React, { useState, useEffect, useCallback } from 'react';
import { View, Text, FlatList, StyleSheet, ActivityIndicator, Image } from 'react-native';
import throttle from 'lodash.throttle';
import useWindowScrollStore from '../store/useWindowScrollStore';

function SocialFeed() {
  const [data, setData] = useState([]);
  const [page, setPage] = useState(1);
  const [loading, setLoading] = useState(false);
  const [hasMore, setHasMore] = useState(true);

  // Fetch data from the DummyJSON API
  const fetchData = async () => {
    if (loading) return;

    setLoading(true);
    try {
      const response = await fetch(`https://dummyjson.com/products?limit=10&skip=${(page - 1) * 10}`);
      const result = await response.json();

      if (result.products.length > 0) {
        setData((prevData) => [...prevData, ...result.products]);
        setPage(page + 1);
      } else {
        setHasMore(false);
      }
    } catch (error) {
      console.error('Error fetching data:', error);
    } finally {
      setLoading(false);
    }
  };

  // Initial fetch
  useEffect(() => {
    fetchData();
  }, []);

  const onListScroll = useCallback(
    throttle((nativeEvent) => {
      useWindowScrollStore.getState().setScrollY(nativeEvent.contentOffset.y);
    }, 100),
    []
  );

  const renderItem = ({ item }) => (
    <View style={styles.postContainer}>
      <Image source={{ uri: item.thumbnail }} style={styles.image} />
      <Text style={styles.postText}>{item.title}</Text>
      <Text style={styles.descriptionText}>{item.description}</Text>
    </View>
  );

  const renderFooter = () => {
    if (!loading) return null;
    return <ActivityIndicator size="large" color="#0000ff" />;
  };

  return (
    <View style={styles.container}>
      <FlatList
        data={data}
        renderItem={renderItem}
        keyExtractor={(item) => item.id.toString()}
        onScroll={({ nativeEvent }) => onListScroll(nativeEvent)}
        onEndReached={hasMore ? fetchData : null}
        onEndReachedThreshold={0.5}
        ListFooterComponent={renderFooter}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 10,
  },
  postContainer: {
    backgroundColor: '#f0f0f0',
    padding: 15,
    marginVertical: 8,
    borderRadius: 10,
  },
  postText: {
    fontSize: 16,
    color: '#333',
    fontWeight: 'bold',
  },
  descriptionText: {
    fontSize: 14,
    color: '#666',
    marginTop: 5,
  },
  image: {
    width: '100%',
    height: 200,
    borderRadius: 10,
    marginBottom: 10,
  },
});

export default SocialFeed;

What I’ve Tried:

  • Throttling the onScroll event using lodash.throttle.
  • Using useMemo and useCallback to optimize the rendering of list items.
  • Implementing performance improvements by reducing re-renders and optimizing state updates.

The Problem:

Despite these optimizations, the onScroll event still lags or stops firing correctly when the list becomes large. This issue affects the header, footer, and action button toggle functionality, making them unresponsive to scroll events.

Question:

How can I improve the responsiveness of the onScroll event in a FlatList with large datasets? Are there other optimization techniques I should consider for better performance and a smoother scroll experience?

Any advice or suggestions would be greatly appreciated!

Error: Cannot find module ‘./types/express’ when running TypeScript project with ts-node

Iam geting 2 errors that are below , created the src/types/express.d.ts and

 `declare global {
             namespace Express {
             interface Request {
               user?: any;
                  }
                 }
                  }

                 export {}; // This line makes this file a module`

if i remove the import in the src/index.ts Property ‘user’ does not exist on type ‘Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>’.
enter image description here
if i import it import "./types/express";
the error

enter image description here

Tsconfig.json

{ "compilerOptions": { "target": "ES6", "module": "commonjs", "outDir": "./dist", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true, "typeRoots": ["./node_modules/@types", "./src/types"] }, "include": ["src/**/*.ts", "src/types/**/*.d.ts"] }

i tried to to add the user to the request in the express.js

not able to interact with monaco editor api in leetcode

I am working on a chrome extension where I want to inject some piece of text into monaco code editor present on leetcode.

I am tring to access the monaco api through chrome extension but I am failing to do so, but if I type window.monaco in console of browser it shows the monaco object.

Following is the code I am using for accessing monaco object

manifest.json

{
  "manifest_version": 3,
  "name": "LeetCode Template Injector",
  "version": "1.0",
  "description": "Insert algorithm templates into LeetCode editor.",
  "permissions": ["activeTab", "scripting"],
  "action": {},
  "content_scripts": [
    {
      "matches": ["https://leetcode.com/problems/*"],
      "js": ["content.js"]
    }
  ]
}

content.js

function checkMonacoEditor() {
  const interval = setInterval(() => {
    if (typeof monaco !== "undefined" && monaco.editor.getModels().length > 0) {
      console.log("monaco editor found");
    } else {
      console.log("Waiting for Monaco editor...");
    }
  }, 1000);
}

window.addEventListener("load", function () {
  checkMonacoEditor();
});

Here is a screenshot of my browser console

enter image description here

How to implement scroll-based video switching like YouTube Shorts in HTML/CSS/JavaScript?

I’m working on a video container design using HTML, CSS, and JavaScript, and I want to implement a feature where scrolling automatically switches to the next video, similar to how YouTube Shorts behaves.

I have a basic design where I load a video, along with interaction buttons like follow, like, comment, and share. However, I need help with the JavaScript functionality that allows the video to change when the user scrolls past the current one.

Here’s my HTML structure:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Shorts Design</title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="container">
        <!-- Video Section -->
        <div class="video-container">
            <video id="video-player" src="videos/video1.mp4" controls></video>
            <!-- Follow Button -->
            <button class="follow-button">Follow</button>

            <!-- Interaction buttons on the video player -->
            <div class="actions">
                <div class="action-button like">
                    <span><i class="fa-regular fa-heart"></i></span>
                    <span>452</span>
                </div>
                <div class="action-button comment">
                    <span><i class="fa-regular fa-comment"></i></span>
                    <span>6</span>
                </div>
                <div class="action-button share">
                    <span><i class="fa-solid fa-share"></i></span>
                    <span>Share</span>
                </div>
            </div>
        </div>
    </div>

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

And here’s my CSS:

/* Global Styles */
body, html {
    margin: 0;
    padding: 0;
    overflow-x: hidden;
}

.container {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    overflow: hidden;
}

.video-container {
    width: 100%;
    height: 100%;
}

video {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: Arial, sans-serif;
}

body {
    background-color: #181818;
    color: white;
}

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
    padding: 20px;
    height: 100vh;
}

/* Video Section */
.video-container {
    width: 100%;
    max-width: 400px;
    height: 800px;
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
}

video {
    width: 100%;
    height: 100%;
    border-radius: 10px;
    position: relative;
}

/* Follow Button */
.follow-button {
    position: absolute;
    top: 10px;
    right: 10px;
    padding: 8px 12px;
    background-color: #ff0000;
    color: white;
    border: none;
    border-radius: 20px;
    cursor: pointer;
    font-size: 14px;
    transition: background-color 0.3s ease;
}

.follow-button:hover {
    background-color: #cc0000;
}

/* Actions Section: Buttons on the right side of the video */
.actions {
    position: absolute;
    right: 10px;
    top: 20%;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.action-button {
    margin: 10px 0;
    color: white;
    text-align: center;
    cursor: pointer;
    padding: 10px;
    background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent background */
    border-radius: 50%;
    width: 50px;
    height: 50px;
    opacity: 0.8; /* Transparency effect */
    transition: opacity 0.3s ease;
}

.action-button:hover {
    opacity: 1;
}

/* Ensure icons are centered within the buttons */
.action-button span {
    display: block;
}

/* Subscribe Section */
.subscribe-section {
    display: flex;
    align-items: center;
    justify-content: space-between;
    background-color: #333;
    padding: 10px 15px;
    border-radius: 10px;
    max-width: 400px;
    width: 100%;
    margin-top: 10px;
}

.profile-pic {
    width: 50px;
    height: 50px;
    border-radius: 50%;
}

.subscribe-info {
    flex-grow: 1;
    padding-left: 10px;
}

.subscribe-button {
    padding: 10px 15px;
    background-color: #ff0000;
    border: none;
    border-radius: 5px;
    color: white;
    cursor: pointer;
}

/* Responsive Media Queries */
@media (max-width: 768px) {
    .actions {
        right: 5px;
        top: 15%;
    }

    .subscribe-section {
        flex-direction: column;
        align-items: center;
        padding: 15px;
    }

    .profile-pic {
        width: 40px;
        height: 40px;
    }

    .subscribe-button {
        margin-top: 10px;
        width: 100%;
    }
}

@media (max-width: 480px) {
    .video-container {
        max-width: 100%;
    }

    .actions {
        position: static;
        flex-direction: row;
        width: 100%;
        justify-content: space-evenly;
    }
}

The idea is to switch between multiple videos automatically based on the user’s scroll interaction. I have an array of videos and need to load the next one when scrolling. Here’s the JavaScript I’ve tried:

document.addEventListener('DOMContentLoaded', function() {
    const videos = [
        "videos/video1.mp4",
        "videos/video2.mp4",
        "videos/video3.mp4",
        // Add more videos as needed
    ];

    let currentVideoIndex = 0;
    const videoPlayer = document.getElementById('video-player');

    // Function to load the next video
    function loadNextVideo() {
        currentVideoIndex++;
        if (currentVideoIndex >= videos.length) {
            currentVideoIndex = 0; // Loop back to the first video
        }
        videoPlayer.src = videos[currentVideoIndex];
        videoPlayer.play();
    }

    // Using IntersectionObserver to detect when the user scrolls past the current video
    const observer = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                // If the current video is fully visible, play it
                videoPlayer.play();
            } else {
                // If the video is not visible anymore, load the next video
                loadNextVideo();
            }
        });
    }, {
        threshold: 0.75 // Video is considered visible when 75% of it is on screen
    });

    // Observing the video container
    observer.observe(videoPlayer);
});

The Issue:
I want to achieve the same experience as YouTube Shorts, where each scroll jumps directly to the next video. However, I’m not sure if this approach with IntersectionObserver is the best for this case, or if there’s a better way to do this.

What would be the best way to implement this kind of scroll-based video switching?

Edit:
my updated js:

console.log("Scroller");

// Define the video array
const videos = [
    "videos/video1.mp4",
    "videos/video2.mp4",
    "videos/video3.mp4",
    // Add more videos as needed
  ];
  
  // Get the container and video player elements
  const container = document.querySelector('.container');
  const videoPlayer = document.getElementById('video-player');
  
  // Initialize the current video index
  let currentVideoIndex = 0;
  
  // Initialize a flag to indicate whether the user has interacted with the document
  let userHasInteracted = false;
  
  // Add the scroll event listener to the container
  container.addEventListener('scroll', (e) => {
    // Get the video offset and height
    const videoOffset = videoPlayer.offsetTop;
    const videoHeight = videoPlayer.offsetHeight;
  
    // Get the scroll position and direction
    const scrollPosition = container.scrollTop;
    const scrollDirection = e.deltaY > 0 ? 'down' : 'up';
  
    // Check if the user has scrolled down and the current video is no longer visible
    if (scrollDirection === 'down' && scrollPosition > videoOffset + videoHeight - 20) {
      // Load the next video
      loadNextVideo();
    }
  });
  
  // Function to load the next video
  function loadNextVideo() {
    // Increment the current video index
    currentVideoIndex++;
  
    // Loop back to the first video if we've reached the end of the array
    if (currentVideoIndex >= videos.length) {
      currentVideoIndex = 0;
    }
  
    // Update the video player source
    videoPlayer.src = videos[currentVideoIndex];
  
    // If the user has interacted with the document, play the video automatically
    if (userHasInteracted) {
      videoPlayer.play();
    }
  }
  
  // Add an event listener to the document to listen for user interaction
  document.addEventListener('click', () => {
    // Set the flag to indicate that the user has interacted with the document
    userHasInteracted = true;
  
    // If the video is not playing, play it
    if (!videoPlayer.paused) {
      videoPlayer.play();
    }
  });
  
  // Initialize the video player with the first video
  videoPlayer.src = videos[0];

Fetch Telegram API in Google Cloud VM Instance is Failed

So, i want to send Telegram API Bot in Google Cloud VM Instance using Ubuntu latest version or the highest version. I’m using NodeJS program and fetch to run the API.

But i got this error:

TypeError: fetch failed
    at node:internal/deps/undici/undici:13185:13
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async exports.sendMessage (/root/anonymous/controller/telegram/sendMessageController.js:19:21) {
  [cause]: AggregateError [ETIMEDOUT]: 
      at internalConnectMultiple (node:net:1117:18)
      at internalConnectMultiple (node:net:1185:5)
      at Timeout.internalConnectMultipleTimeout (node:net:1711:5)
      at listOnTimeout (node:internal/timers:596:11)
      at process.processTimers (node:internal/timers:529:7) {
    code: 'ETIMEDOUT',
    [errors]: [ [Error], [Error] ]
  }
}

This my code (sendMessageController.js) :

const dotenv = require("dotenv");

dotenv.config();

exports.sendMessage = async (req, res) => {
  const { message } = req.body;

  if (!req.body || Object.keys(req.body).length === 0) {
    return res.status(400).json({
      status: 400,
      message: "Bad request",
    });
  }

  try {
    const token = process.env.TELEGRAM_TOKEN;
    const url = process.env.TELEGRAM_API_URL;
    const channel = process.env.TELEGRAM_CHANNEL_ID;
    const request = await fetch(`${url}/bot${token}/sendMessage`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        chat_id: channel,
        text: message.replace(/[_*[]()~`>#+-=|{}.!-]/g, "\$&"),
        parse_mode: "MarkdownV2",
      }),
    });

    const response = await request.json();

    console.log(response);
    res.status(200).json({ status: 200, message: "Success", data: response });
  } catch (error) {
    console.error(error);
    res.status(500).json({ status: 500, message: "Internal server error" });
  }
};

I’m triggering using REST API, the issue is from this code.

I don’t now what to do, maybe you all experts can figure my problem out. If there’s a question, don’t be shy to ask for it.

Thank you

What i expect is the fetch is working, nothing failed like in Localhost.

React useState() hook not updating

I am trying to save the error API responses for the backend as an array/object using useState hook. to my surprise, the state value did not get updated. (Note: this is a practice challenge from a youtube post)

  const onSubmit = (ev) => {
    ev.preventDefault();

    const payload = { ...survey }; // destructure and create new object payload
    if (payload.image) {
      payload.image = payload.image_url;
    }
    delete payload.image_url;
    let res = null;
    if (id) {
      res = axiosClient.put(`/survey/${id}`, payload);
    } else {
      res = axiosClient.post("/survey", payload);
    }

    res
      .then((res) => {
        console.log(res);
        navigate("/surveys");
        if (id) {
          showToast("The survey was updated");
        } else {
          showToast("The survey was created");
        }
      })
      .catch((err) => {
        if (err && err.response) {
          setError(err.response.data.message);
          setErry('1234');
        }
         console.log(err, err.response);
         console.log(erry)
     
      
  
      });
  };

//the form
 <form action="#" method="POST" onSubmit={onSubmit}>

Another trial to this while trying to isolate the problem

const [count, setCount] = useState(0);

  const increment = (ev) => {
       ev.preventDefault();
      setCount(4);
      alert('The count is ' + count);
  }

//the form
 <form action="#" method="POST" onSubmit={increment }>

// i still get count as 0 every time i click submit.

what am i missing please?

Page refreshes everytime i click on download

I have made this program to generate adj list by visualizing a graph and the problem is when I download a list, the refreshes hence all my work is lost. can you please help?

heres the github link
https://github.com/Ujjwal238/graph-isomorphism
html file is
https://github.com/Ujjwal238/graph-isomorphism/blob/main/html-code.html
and js file is
https://github.com/Ujjwal238/graph-isomorphism/blob/main/javascript-code.js

const workspaces = [{
    vertices: [],
    edges: [],
    canvas: document.getElementById('graphCanvas1'),
    fileName: 'input.txt'
  },
  {
    vertices: [],
    edges: [],
    canvas: document.getElementById('graphCanvas2'),
    fileName: 'input2.txt'
  }
];

let selectedVertex = [null, null];
let draggingVertex = [null, null];
let isDrawingEdge = [false, false];
let isRemovingVertex = [false, false];

function drawVertex(ctx, x, y, index) {
  ctx.beginPath();
  ctx.arc(x, y, 20, 0, 2 * Math.PI);
  ctx.fillStyle = '#3498db';
  ctx.fill();
  ctx.stroke();
  ctx.fillStyle = '#fff';
  ctx.font = '16px Arial';
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.fillText(index, x, y);
}

function drawEdge(ctx, start, end) {
  ctx.beginPath();
  ctx.moveTo(start.x, start.y);
  ctx.lineTo(end.x, end.y);
  ctx.stroke();
}

function redrawGraph(workspaceIndex) {
  const workspace = workspaces[workspaceIndex];
  const ctx = workspace.canvas.getContext('2d');
  ctx.clearRect(0, 0, workspace.canvas.width, workspace.canvas.height);
  workspace.edges.forEach(edge => drawEdge(ctx, workspace.vertices[edge[0]], workspace.vertices[edge[1]]));
  workspace.vertices.forEach((vertex, index) => drawVertex(ctx, vertex.x, vertex.y, index + 1));
}

function addVertex(workspaceIndex) {
  const workspace = workspaces[workspaceIndex - 1];
  const x = Math.random() * (workspace.canvas.width - 40) + 20;
  const y = Math.random() * (workspace.canvas.height - 40) + 20;
  workspace.vertices.push({
    x,
    y
  });
  redrawGraph(workspaceIndex - 1);
}

function toggleRemoveMode(workspaceIndex) {

  const index = workspaceIndex - 1;
  isRemovingVertex[index] = !isRemovingVertex[index];
  const btn = document.querySelector(`#workspace${workspaceIndex} button:nth-child(2)`);
  btn.textContent = isRemovingVertex[index] ? 'Cancel Remove' : 'Remove Vertex';
  workspaces[index].canvas.style.cursor = isRemovingVertex[index] ? 'not-allowed' : 'default';

}

function generateList(workspaceIndex) {
  const workspace = workspaces[workspaceIndex - 1];
  const adjacencyList = [];

  workspace.vertices.forEach((vertex, index) => {
    const neighbors = [];
    workspace.edges.forEach(edge => {
      if (edge[0] === index) {
        neighbors.push(edge[1] + 1);
      } else if (edge[1] === index) {
        neighbors.push(edge[0] + 1);
      }
    });
    adjacencyList.push(`${index + 1} ${neighbors.join(' ')}`);
  });

  const listString = adjacencyList.join('n');
  const blob = new Blob([listString], {
    type: 'text/plain'
  });
  const url = URL.createObjectURL(blob);

  const a = document.createElement('a');
  a.href = url;
  a.download = workspace.fileName;
  a.target = '_blank';
  a.click();
  URL.revokeObjectURL(url);
}

workspaces.forEach((workspace, index) => {
  workspace.canvas.addEventListener('mousedown', (event) => handleMouseDown(event, index));
  workspace.canvas.addEventListener('mousemove', (event) => handleMouseMove(event, index));
  workspace.canvas.addEventListener('mouseup', () => handleMouseUp(index));
  workspace.canvas.addEventListener('dblclick', (event) => handleDoubleClick(event, index));
});

function handleMouseDown(event, workspaceIndex) {
  const workspace = workspaces[workspaceIndex];
  const rect = workspace.canvas.getBoundingClientRect();
  const x = event.clientX - rect.left;
  const y = event.clientY - rect.top;

  const clickedVertexIndex = workspace.vertices.findIndex(v =>
    Math.sqrt((v.x - x) ** 2 + (v.y - y) ** 2) < 20
  );

  if (clickedVertexIndex !== -1) {
    if (isRemovingVertex[workspaceIndex]) {
      workspace.vertices.splice(clickedVertexIndex, 1);
      workspace.edges = workspace.edges.filter(edge => edge[0] !== clickedVertexIndex && edge[1] !== clickedVertexIndex);
      workspace.edges = workspace.edges.map(edge => [
        edge[0] > clickedVertexIndex ? edge[0] - 1 : edge[0],
        edge[1] > clickedVertexIndex ? edge[1] - 1 : edge[1]
      ]);
      redrawGraph(workspaceIndex);
      isRemovingVertex[workspaceIndex] = false;
      toggleRemoveMode(workspaceIndex + 1);
    } else if (isDrawingEdge[workspaceIndex]) {
      if (selectedVertex[workspaceIndex] !== clickedVertexIndex) {
        workspace.edges.push([selectedVertex[workspaceIndex], clickedVertexIndex]);
        redrawGraph(workspaceIndex);
      }
      isDrawingEdge[workspaceIndex] = false;
      selectedVertex[workspaceIndex] = null;
      workspace.canvas.style.cursor = 'default';
    } else {
      draggingVertex[workspaceIndex] = clickedVertexIndex;
      workspace.canvas.style.cursor = 'grabbing';
    }
  } else {
    isDrawingEdge[workspaceIndex] = false;
    selectedVertex[workspaceIndex] = null;
    workspace.canvas.style.cursor = 'default';
  }
}

function handleMouseMove(event, workspaceIndex) {
  const workspace = workspaces[workspaceIndex];
  const rect = workspace.canvas.getBoundingClientRect();
  const x = event.clientX - rect.left;
  const y = event.clientY - rect.top;

  if (draggingVertex[workspaceIndex] !== null) {
    workspace.vertices[draggingVertex[workspaceIndex]].x = x;
    workspace.vertices[draggingVertex[workspaceIndex]].y = y;
    redrawGraph(workspaceIndex);
  }
}

function handleMouseUp(workspaceIndex) {
  if (draggingVertex[workspaceIndex] !== null) {
    draggingVertex[workspaceIndex] = null;
    workspaces[workspaceIndex].canvas.style.cursor = 'default';
  } else if (selectedVertex[workspaceIndex] !== null) {
    isDrawingEdge[workspaceIndex] = true;
    workspaces[workspaceIndex].canvas.style.cursor = 'crosshair';
  }
}

function handleDoubleClick(event, workspaceIndex) {
  const workspace = workspaces[workspaceIndex];
  const rect = workspace.canvas.getBoundingClientRect();
  const x = event.clientX - rect.left;
  const y = event.clientY - rect.top;

  const clickedVertexIndex = workspace.vertices.findIndex(v =>
    Math.sqrt((v.x - x) ** 2 + (v.y - y) ** 2) < 20
  );

  if (clickedVertexIndex !== -1) {
    selectedVertex[workspaceIndex] = clickedVertexIndex;
    isDrawingEdge[workspaceIndex] = true;
    workspace.canvas.style.cursor = 'crosshair';
  }
}
body {
  font-family: Arial, sans-serif;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 0;
  background-color: #f0efef;
}

.container {
  display: flex;
  justify-content: space-around;
  width: 100%;
  max-width: 1200px;
}

.workspace {
  text-align: center;
}

.graphCanvas {
  border: 1px solid #000;
  background-color: #fff;
  cursor: default;
}

button {
  margin: 10px;
  padding: 5px 10px;
  font-size: 16px;
}

.red-button {
  background-color: red;
  /* color: white; optional, to change the text color */
}
<div class="container">
  <div id="workspace1" class="workspace">
    <h2>Graph 1 (input.txt)</h2>
    <canvas id="graphCanvas1" class="graphCanvas" width="400" height="400"></canvas>
    <br>
    <button onclick="addVertex(1)">Add Vertex</button>
    <button onclick="toggleRemoveMode(1)">Remove Vertex</button>
    <button onclick="generateList(1)">Generate Adjacency List</button>
  </div>
  <div id="workspace2" class="workspace">
    <h2>Graph 2 (input2.txt)</h2>
    <canvas id="graphCanvas2" class="graphCanvas" width="400" height="400"></canvas>
    <br>
    <button onclick="addVertex(2)">Add Vertex</button>
    <button onclick="toggleRemoveMode(2)">Remove Vertex</button>
    <button onclick="generateList(2)">Generate Adjacency List</button>
  </div>
</div>
<script src="javascript-code.js"></script>

the download part

const a = document.createElement('a');
    a.href = url;
    a.download = workspace.fileName;
    a.target = '_blank';
    a.click();
    URL.revokeObjectURL(url);

i have tried Ai,s help but all it gives are redundant answers. `

How can I contribute to beginner-friendly open-source projects in JavaScript and React as a college student?

I’m a college student with experience in JavaScript and React, and I want to start contributing to open-source projects. While I’ve researched how to get started, most resources I’ve found are too general, and I’m struggling to find projects that are beginner-friendly and relevant to my skills.

I’ve tried searching for issues labeled “good first issue” and “beginner-friendly” on GitHub, but many projects seem inactive or advanced for my level. I also want to know the best way to approach maintainers and how to submit my first meaningful pull request.

Any recommendations for active open-source projects that welcome beginners in web development, or tips on how to navigate the contribution process, would be really appreciated.

Line chart issue is chart.js

enter image description here
Hello I have an issue with my chart it only fills up halfway.

The code is bellow and when I only update the temperature the graph will be okay and when I add the humidity the chart is only filling up halfway

// Declare chart variables
let temperatureChart;
let humidityChart;

// Function to create the temperature and humidity charts
function createCharts() {
    const ctxTemp = document.getElementById('temperatureChart').getContext('2d');
    const ctxHum = document.getElementById('humidityChart').getContext('2d');

    // Create the temperature chart
    temperatureChart = new Chart(ctxTemp, {
        type: 'line',
        data: {
            labels: [],
            datasets: [{
                label: 'Temperature (°C)',
                data: [],
                borderColor: 'rgba(255, 99, 132, 1)',
                borderWidth: 2,
                fill: false,
                tension: 0.4  // Smooth the line
            },{
                label: 'Humidity (%),
                data: [],
                borderColor: 'rgba(255, 99, 132, 1)',
                borderWidth: 2,
                fill: false,
                tension: 0.4  // Smooth the line
        }]
        },
        options: {
            scales: {
                x: {
                    title: {
                        display: true,
                        text: 'Time'
                    }
                },
                y: {
                    min: 0,  // Minimum value for temperature
                    max: 60, // Maximum value for temperature
                    title: {
                        display: true,
                        text: 'Temperature (°C)'
                    }
                }
            },
            animation: {
                duration: 0  // Disable animation to make it feel more real-time
            }
        }
    });

    // Create the humidity chart
    humidityChart = new Chart(ctxHum, {
        type: 'line',
        data: {
            labels: [],
            datasets: [{
                label: 'Humidity (%)',
                data: [],
                borderColor: 'rgba(54, 162, 235, 1)',
                borderWidth: 2,
                fill: false,
                tension: 0.4  // Smooth the line
            }]
        },
        options: {
            scales: {
                x: {
                    title: {
                        display: true,
                        text: 'Time'
                    }
                },
                y: {
                    min: 0,   // Minimum value for humidity
                    max: 100, // Maximum value for humidity
                    title: {
                        display: true,
                        text: 'Humidity (%)'
                    }
                }
            },
            animation: {
                duration: 0  // Disable animation to make it feel more real-time
            }
        }
    });
}

// Function to update the charts with new data
function updateCharts(data) {
    const currentTime = new Date().toLocaleTimeString([], {hour: '2-digit', minute: '2-digit', second: '2-digit'});  // Get current time as "hh:mm:ss AM/PM"
    
    // Update the display box with the latest data
    document.getElementById('temperature').textContent = `${data.temperature}°C`;
    document.getElementById('humidity').textContent = `${data.humidity}%`;

    // Add the new data points to the charts
    temperatureChart.data.labels.push(currentTime);
    temperatureChart.data.datasets[0].data.push(data.temperature);
    humidityChart.data.labels.push(currentTime);
    humidityChart.data.datasets[0].data.push(data.humidity);

    // Update the charts
    temperatureChart.update();
    humidityChart.update();
}

window.onload = function() {
    createCharts();
    setInterval(fetchData, 1000);
}

I am having a hard time solving this issue. I am sorry for the troubles

event.preventDefault cannot block clipboard paste in chatgpt.com prompt box

I’m using following codes to block paste to certain webpages

document.addEventListener('paste', (event) => {
    event.preventDefault();
});

It works in most cases except for prompt box in https://chatgpt.com. here is what i did step by step:

  1. open https://chatgpt.com with chrome for windows
  2. open console and run above codes
  3. copy some texts and paste to prompt box with CTL+v or rightclick->paste
  4. texts are pasted successfully

I wonder how it pasts text and is there any way to block it.

How to make Image Magick upscaling operation run much faster? (It currently takes 10 seconds per image…)

My current workflow resizes/upscales images using Image Magick inside of an AWS Lambda function.

It uses the Image Magick layer, and the code is written in node.js as follows:

    // Step 1: Download the image from S3
    console.log("Downloading image from S3 bucket:", bucket, "with key:", key);
    const inputImagePath = path.join(os.tmpdir(), 'input.jpg');
    const outputImagePath = path.join(os.tmpdir(), 'resized-image.jpg');

    const downloadImageFromS3 = async () => {
        const getObjectCommand = new GetObjectCommand({ Bucket: bucket, Key: key });
        const s3Object = await s3Client.send(getObjectCommand);
        await pipeline(s3Object.Body, fs.createWriteStream(inputImagePath));
    };

    await downloadImageFromS3();
    console.log("Image downloaded successfully!");

    // Step 2: Resize the image using ImageMagick
    console.log(`Resizing image to ${desiredWidth}x${desiredHeight}...`);
    const command = `convert ${inputImagePath} -adaptive-resize ${desiredWidth}x${desiredHeight}! -density 300x300 ${outputImagePath}`;
    execSync(command);
    console.log("Image resized successfully!");

Since the images get upscaled to fairly large sizes (6000+ pixels for either the width or height), it takes the operation about 10 seconds to complete.

Things I have tried:

  1. I’ve tried increasing the memory allocation of the Lambda function to the currently-max-allowable 3008 MB. (I have also requested that my account be given access to the absolute maximum 10,280 MB level as well, to see if that will help speed it up.) “Max Memory Used” caps out at a surprisingly low level, around 300-500 MB. Is there any way I can somehow force it to use more CPU resources to process it faster? Like some kind of Image Magick and/or AWS Lambda command that explicitly says “use as much CPU power to do this as fast as possible”?

  2. Compressing the images in that same convert command, to see if it would return the output faster. This had no apparent impact on speed.

  3. Using a method that is not adaptive resize. “-resize” does execute about 2x faster. BUT the final image quality is poor — and the very best image quality is required for this workflow (and I’ve found “adaptive resize”, by far, produces the best-looking outputs.)

Other ideas I have:

  1. Since I need to resize each image to several slightly-different aspect ratios, instead of doing it sequentially in a loop, could I instead write the code to execute all of these different operations simultaneously — so instead of doing 3 in a row that takes 30 seconds total, all 3 can execute and finish at roughly the same time and therefore only take 10 seconds total?

  2. Is there a way to just avoid the “download my image” step altogether? Any way I can just have the upscaling operation act directly on the image that’s already in my S3 bucket? Like, have the Lambda function somehow pipe directly in there to just act on it instead of that intermediate download step where it gets converted to image data and that gets passed to Image Magick?

Any ideas/tips would be HIGHLY appreciated. Thank you!

The subject of closures and React useState hook

very young Padawan in the React universe here,

This question revolves around the inner mechanisms of the useState() hook. My gratitude in advance for your time taken! and my sincerest apologies for the lengthy post.

Would this explanation perfectly describe what is going on ?

Looking at the 1st challenge (Challenge 1 of 2: Fix a request counter)in the page: Queueing a series of state updates within the React.dev DOCs,

this line of code exists within the function component:

async function handleClick() {
    setPending(p => p + 1);
    await delay(3000);
    setPending(p => p - 1);
    setCompleted(c => c + 1);
  }

I modify this code to alert(pending) state variable to test a hypothesis in mind:

async function handleClick() {
    setPending(p => p + 1);
    await delay(3000);

    alert(pending)

    setPending(p => p - 1);
    setCompleted(c => c + 1);
  }

My explanatory attempt :

We learn that React batches multiple set state functions that occur within a single event trigger for its efficiency.

Without an async nature and delay present, for the first click after initial render, the alert() will display 0 since the state variable passed into it isnt the updated value, rather a snapshot of the state at the time of event triggering.

This is due to the fact that the state variable updates only after all code in event trigger function finishes running.

However in cases such as mentioned above, the batching breaks due to the function’s async nature. Specifically in the first setPending() before delay.

Here, the setPending() increments the pending variable and goes ahead and re-renders the component to reflect the changes, hence why we see the number change in the DOM.

After the delay, the alert() displays a surprising 0, along with the visual DOM change of pending and completed due to the followed setPending() that decrements the value and setCompleted().

Due to the batch breaking which re-renders the component and updates pending state variable’s value before the delay, it is expected that alert() receives the updated value.

But.. due to the concept of closure, the event trigger’s function does not have access to the updated values of state variables after the update, rather it owns the value at the start of event trigger, which in this case is initializer 0.

<button> click again will alert() the value 1 instead of actuall updated pending value of 2.

The following mentioned effects can be attributed to JS closure behavior and batch breaking.

Side note: I realllly wish React docs would have “Deep Dived” into this.

Thank you so much !

UI elements jitter when being conditionally rendered

I’m have an issue where buttons and links jitter on state change (when clicking on the “Sign Out” button). I tried both v-if and v-show and the jitter persists.
Video of the issue: https://www.veed.io/view/89672f51-f55c-411c-883f-440b02cfa4de?panel=share

<div>
  <div>
      <button @click="setColorTheme()">
          <IconDarkMode />
      </button>
      <div v-if="!signedIn && !pending">
          <NuxtLink to="/sign-in">
              <span>Sign In</span>
              <IconSignIn />
          </NuxtLink>
      </div>
  </div>
  <div
      v-if="signedIn && !pending">
      <NuxtLink to="/profile">
          <span>Profile</span>
          <IconProfile />
      </NuxtLink>
      <button to="/sign-in" @click="signOut">
          <span>Sign Out</span>
          <IconSignOut />
      </button>
  </div>
</div>

I also have a 300ms delay for signedIn state in signOut function to wait until page transition ends, but jitter still persists.

if (res.ok) {
    const data = await res.json();
    state.successMessage = data.message;
    if (route.path === '/') {
        window.location.reload();
    } else {
        window.location.href = '/';
    }
    setTimeout(() => {
        state.signedIn = data.signedIn;
    }, 300);
}

Looking for a possible solution.