how to disable next button when the input is empty

i’m tring to create a multiple login form , every was fine but i want to disable next button if the email input is empty.
the input class=”email”
and the button class =”btn-next”
i will appreciate any help thanks.

<sub>const pageBox = document.querySelector('.page-box');
const btnNext = document.querySelector('.btn-next');
const btnBack = document.querySelector('.btn-back');
const checkboxPass = document.querySelector('.checkbox-pass');
const passwordInput = document.querySelector('.password');
const loginTitle = document.querySelector('.loginTitle-text');
const userEmail = document.querySelector('.user-email');
const emailInput = document.querySelector('.email');

btnNext.onclick = (e) => {
    e.preventDefault();
    pageBox.classList.add('active-pass');
    setTimeout(() => passwordInput.focus(), 500);
    loginTitle.innerHTML = 'Welcome';
    userEmail.innerHTML = ''  + emailInput.value;
};

btnBack.onclick = (e) =>{
    e.preventDefault();
    pageBox.classList.remove('active-pass');
    loginTitle.innerHTML = 'Sign in';
    userEmail.innerHTML = 'Please continue,';
    emailInput.focus();
};

checkboxPass.onclick = () => {
    if(checkboxPass.checked) {
        passwordInput.type = 'text';
    }
    else{
       passwordInput.type = 'password';
    }
};
emailInput.addEventListener("btnNext", (e) => {
    preventDefault();
    btnNext.disabled()
    if(emailInput.value.length  > 0) {
        btnNext.disabled = 'true';
     }
     else{
        btnNext.disabled = 'false';
    } 
});
</sub>

increase why does this not work in reactjs?

been working with useState hook in reactjs where i tried to increase the value of count upon clicking the button. but nothing is rendered on my page, not even the button. Could you tell me how I fix it?

i tried using onclick handler which i thought would trigger the setCount function once the event is triggered, increasing the value of count by 1.

How do I get my ejs form to autofill the ID value for the person filling out the form?

Essentially, the user is creating an event, and I want the user’s id to be autofilled as the organizer value.
Currently, the event is created by the user filling out a form with all the necessary details (title, location, etc.). But I want it to autofill ID and submit that with the rest of the data

I was trying something like this, but it’s throwing errors and telling me that the id value is undefined, even though my code has no problems grabbing that value when using it to show that person’s name on the home screen

Here’s the part of the form as it currently stands:

<label for="inputOrganizer">Organizer ID:</label> <br/> <input type="mongoose.Schema.Types.ObjectId" name="organizer" id="inputOrganizer" placeholder="Organizer" value="<%= currentUser._id %>" required />

(On the home screen, to show the person’s name by searching for them via ID, I have this code:

<% if (loggedIn) { %> Logged in as <a href="<%=/users/${currentUser._id}%>"><%= currentUser.name %></a>
(note that there’s a ` before and after the /users string but it won’t show it because that’s used to put it in a text box thingy)

and that works fine. Replacing “._id” with “.name” didn’t fix the error, nor did putting it in the ${} thing.)

Odoo 16 – Modify Examples in Project Module

I’m trying to modify the examples in Project Module:

But I can’t update the ‘project’ registry ..

enter image description here

I have created a new registry 

odoo.define("restructure_inherit_views.extend_project_task_kanban_examples", function(require) {
    "use strict";
    var kanbanExamplesRegistry = require("web.kanban_examples_registry");
    var {
        _lt
    } = require("web.core");
    var {
        registry
    } = require("@web/core/registry");
    var {
        renderToMarkup
    } = "@web/core/utils/render";
    const {
        markup
    } = owl;
    const greenBullet = markup(`<span class="o_status d-inline-block o_status_green"></span>`);
    const redBullet = markup(`<span class="o_status d-inline-block o_status_red"></span>`);
    const star = markup(`<a style="color: gold;" class="fa fa-star"></a>`);
    const clock = markup(`<a class="fa fa-clock-o"></a>`);
    const exampleData = {
        ghostColumns: [_lt("New"), _lt("Assigned"), _lt("In Progress"), _lt("Done"), ],
        applyExamplesText: _lt("Use This For My Project"),
        allowedGroupBys: ["stage_id"],
        examples: [{
            name: _lt("New Custom Example"),
            columns: [_lt("Brainstorm"), _lt("Research"), _lt("Draft"), _lt("Final Document"), ],
            get description() {
                return renderToMarkup("project.example.researchproject");
            },
            bullets: [greenBullet, redBullet],
        }, ],
    };
    kanbanExamplesRegistry.add("custom_project", exampleData);
    registry.category("kanban_examples").add("custom_project", exampleData);
});


But now I don’t know how to use this registry.
Any Help please

How do I reset an array filter when a new “option” is selected? (React)

I have been trying to make a category filter for my webshop project that I’ve been working on. I’m fairly new to React/JavaScript, so I’m probably missing something very obvious.

 {!loading
            ? webshopData.categories?.map((item) => {
                const filtered = products.filter((obj) =>
                  item.products.$each.includes(obj._id)
                );

                return (
                  <div
                    className="productsCategorySelector"
                    onClick={() => setProducts(filtered)}
                    key={item.name}
                  >
                    <p className="label-form productsCategoryLabel">
                      {item.name}
                    </p>
                  </div>
                );
              })
            : null}

When I press on the filter, my products do get filtered, but I need to use another function to get my products back. They are saved in a “productsUnsorted” hook/state.

{!webshopData.categories && (
            <p style={{ marginBottom: 20 }}>All products</p>
          )}
          <p
            className="productsAllShow"
            onClick={() => setProducts(productsUnsorted)}
          >
            All products
          </p>

How can I always reset my array to the default (all products shown) when clicking on a new filter? Right now it just overwrites the changes I made with the filtering function, which means that if I filter products that are in the same category, they won’t show up until I’ve hit the “reset” (productsUnsorted) switch. Is there some way that I can reset the array to the “default” state before filtering via. another category? How can I avoid “keep mutating my array” after the one filter has been applied?

I’ve been sat here for hours trying to figure this out. I tried a bunch of things, but none worked. I just simply don’t understand the logic behind what I’m trying to achieve.

Type ‘IconDefinition’ is not assignable to type ‘IconProp’ in FontAwesome with React

I’m working on a React application using FontAwesome icons. When attempting to render icons using the FontAwesomeIcon component from @fortawesome/react-fontawesome, I encountered the following error:

Type 'IconDefinition' is not assignable to type 'IconProp'.
  Type 'IconDefinition' is not assignable to type 'IconLookup'.
    Types of property 'prefix' are incompatible.
      Type 'import(...).IconPrefix' is not assignable to type 'import(...).IconPrefix'.
        Type '"fast"' is not assignable to type 'IconPrefix'. Did you mean '"fas"'?

Here’s a snippet of my code:

import React from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
  faInstagram,
  faFacebook,
  faLinkedin,
  faDiscord,
  faLinkedinIn,
} from "@fortawesome/free-brands-svg-icons";
import styled from "styled-components";
import contactcss from "./Contact.module.css";
import Card from "../../components/ui/Card";
import { blueHex } from "../../colors";
import grid from "../../resources/blueGrid.png";

// Styled component for the main page container
const Page = styled.div`
  color: ${blueHex};
  padding: 20px;
  min-height: calc(100vh - 84px);
  text-align: left;
  display: flex;
  flex-direction: row;
  align-items: center;
  background: url(${grid});
  background-repeat: repeat;
  background-size: cover;

  @media only screen and (max-width: 768px) {
    height: calc(100vh - 80px);
  }

  @media only screen and (max-width: 425px) {
    padding: 5px;
  }
`;

function Contact() {
  return (
    <div>
      <div>
        <Page>
          <div>
            <div className={contactcss.contact}>Contact Us</div>
          </div>
        </Page>
      </div>

      <div className={contactcss.card}>
        <Card
          title="We're keen to hear from you!"
          imageUrl="https://images.app.goo.gl/D6m6hHMnP1gjsKKV7"
          body=""
        />
      </div>

      <div className={contactcss.greenbackground}>
        <div className={contactcss.socials}>
          <h1 className={contactcss.oursocials}>Our Socials</h1>
          <p className={contactcss.socialmedia}>
            Stay connected with us through our social channels
          </p>

          <div className={contactcss.socialcircles}>
            <div className={contactcss.circle}></div>
            <div className={contactcss.instagramcircle}></div>
            <div className={contactcss.discordcircle}></div>
            <div className={contactcss.linkedincircle}></div>
          </div>

          <div className={contactcss.sociallogos}>
            <a href="https://www.instagram.com/gdscusyd/">
              <FontAwesomeIcon
                className={contactcss.instagram}
                icon={faInstagram}
              />
            </a>

            <a href="https://www.facebook.com/gdsc.usyd">
              <FontAwesomeIcon
                className={contactcss.facebook}
                icon={faFacebook}
              />
            </a>

            <a href="https://discord.com/channels/872033047652990986/872033047652990989">
              <FontAwesomeIcon
                className={contactcss.discord}
                icon={faDiscord}
              />
            </a>

            <a href="https://www.linkedin.com/company/gdsc-usyd/">
              <FontAwesomeIcon
                className={contactcss.linkedin}
                icon={faLinkedinIn}
              />
            </a>
          </div>
        </div>
      </div>

      <div className={contactcss.bluetext}>
        <h1 className={contactcss.joinclub}>Join the club today !</h1>
        <p className={contactcss.foraccess}>
          For access to our amazing events and competitions
        </p>
        <a
          href="https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?client_id=857409878587-im3f0si9p11h41a6aeiil7cs37frkubb.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fgdsc.community.dev%2Faccounts%2Fgoogle%2Flogin%2Fcallback%2F&scope=profile%20email&response_type=code&state=hLlU8pFhaSiq&access_type=offline&service=lso&o2v=1&theme=glif&flowName=GeneralOAuthFlow"
          target="_blank" // Opens the link in a new tab/window
          className={contactcss.joinusbutton}
        >
          Join Us
        </a>
      </div>

      <div className={contactcss.diagonalbluebackground}></div>
      <div className={contactcss.blankbackground}></div>
    </div>
  );
}

export default Contact;

Could someone help me understand why this error is occurring and how to resolve it? I’ve checked my imports and usage of FontAwesome icons, but I’m still facing this issue..I’ve even utilised the correct packages such as ‘@fortawesome/react-fontawesome’.

Additional Information:

Using React v17.0.2
FontAwesome packages:
@fortawesome/react-fontawesome
@fortawesome/free-brands-svg-icons

In a Next.js app, fetching some dummy data and display it on the screen

I am trying to fetch some dummy data from an API and display it on the screen but nothing shows up. the data itself appears in the console but not on the screen

function Shop() {
  const [productsData, setProductsData] = useState([]);
  const [showProductOptions, setShowProductOptions] = useState(false);

  useEffect(() => {
    async function productsData() {
      const res = await fetch('https://dummyjson.com/products');
      const data = await res.json();
      productsData = data.products;
      console.log(productsData);
    }
    productsData();
  });

  return (
    <div>
      <div className={styles.shoppingCard}>
        {productsData.map(product => (
          <li key={product.id} className={styles.product}>
            <Image
              src={image}
              alt="a girl"
              width={100}
              height={100}
              priority
              onClick={() => setShowProductOptions(!showProductOptions)}
            />
            <p className={styles.title}>{product.title}</p>
            <p className={styles.price}>{product.price}</p>
            {showProductOptions && (
              <div>
                <MdOutlineSearch />
                <BsCart3 />
                <BsShuffle />
              </div>
            )}
          </li>
        ))}
      </div>
    </div>
  );
}

export default Shop;

Is there anything I am missing?

ReactEditText. Crash on React Native 0.64.x

In my React Native Android application, I’m encountering a runtime error that I’m having trouble resolving. The error message is as follows:

Fatal Exception: java.lang.NullPointerException
Attempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(android.content.res.Resources)' on a null object reference

The error occurs in the following stack trace:

android.graphics.drawable.DrawableContainer$DrawableContainerState.createAllFutures (DrawableContainer.java:880)
androidx.appcompat.widget.AppCompatEditText.<init> (AppCompatEditText.java:65)
com.facebook.react.views.textinput.ReactEditText.<init> (ReactEditText.java:124)
com.facebook.react.views.textinput.ReactTextInputManager.createViewInstance (ReactTextInputManager.java:123)
com.facebook.react.views.textinput.ReactTextInputManager.createViewInstance (ReactTextInputManager.java:79)
com.facebook.react.uimanager.ViewManager.createViewInstance (ViewManager.java:139)
com.facebook.react.uimanager.ViewManager.createView (ViewManager.java:83)
com.facebook.react.uimanager.NativeViewHierarchyManager.createView (NativeViewHierarchyManager.java:281)
com.facebook.react.uimanager.UIViewOperationQueue$CreateViewOperation.execute (UIViewOperationQueue.java:188)
com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.dispatchPendingNonBatchedOperations (UIViewOperationQueue.java:1103)
com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded (UIViewOperationQueue.java:1074)
com.facebook.react.uimanager.GuardedFrameCallback.doFrame (GuardedFrameCallback.java:29)
com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame (ReactChoreographer.java:175)
com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame (ChoreographerCompat.java:85)
android.view.Choreographer$CallbackRecord.run (Choreographer.java:973)

I’ve tried various debugging methods, but I’m unable to pinpoint the exact cause of this error. It seems to be related to the creation of a React Native TextInput component.

Has anyone encountered a similar issue before or can provide guidance on how to resolve this NullPointerException? Any insights or suggestions would be greatly appreciated. Thank you!

enter image description here

FFmpeg doesn’t produce a ‘progress’ event when converting to videos of certain file types

I am writing an app in electron, and one of the functionalities is that you can create a copy of the currently selected file with a different type. I do this by having a dropdown in the html that allows you to select the type. I then use a function in preload.js that calls an ffmpeg function in main.js

Preload:

const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('changeFiles', {
    //This is the function that is called
    convert: (filePath, newFormat) => ipcRenderer.send('change:file:convert-format', filePath, newFormat)
})

Main:

//electron
const { app, BrowserWindow, ipcMain} = require('electron')

//node
const path = require('path')


//ffmpeg setup
const ffmpegStatic = require('ffmpeg-static')
const ffmpeg = require('fluent-ffmpeg')
ffmpeg.setFfmpegPath(ffmpegStatic)

//imports an array that has video formats ['.mp4', '.webm', '.avi'] and so on
const { videoFormat } = require('./file formats.js')

//Preload sends to this
ipcMain.on('change:file:convert-format', (_event, filePath, newFormat) => {
    //There is an if statement to another function because I want to be able to convert images in the future
    if(videoFormats.includes(newFormat)) {
        videoConvert(filePath, newFormat, _event)
        return
    }
})

const videoConvert = (file, newFormat, _event) => {
    //file is the filepath for the file you want to change

    ffmpeg()
        .input(file)
        .saveToFile(`${path.resolve(path.dirname(file), path.parse(file).name + newFormat)}`)
        .on('progress', (progress) => {
             console.log(progress)
        })
        .on('error', (error) => {
            console.log(error)
        })
}

For some reason, when the format for the video is ‘.mp4’, the .on(‘progress’) fires, but if the format is ‘.webm’ or ‘.avi’ then it is not fired. There are also some issues I have noticed, where if these formats are chosen, then the files may partially be copied over to the new file.

I don’t know if this is because of how I am handling this, a mistake I have made in the .saveToFile(), or something else. No part of this code produces any errors anywhere, the only errors being that the progress doesn’t fire and that the files are not always copied over correctly into the new format.

What should I do?

Template literals, Font Awesome, chessboard.js

I’m creating a chess game using the CSS and JS libraries for chessboard.js and chess.js. For some reason chessboard.js was unable to access its chess piece images, so I decided to use the icons that are on awesome font. For some reason I’m getting a 404 error from | return ‘`; |. Here’s all my code:

var board, game = new Chess();

// Custom piece theme using Font Awesome icons
function pieceTheme(piece) {
  // Map chess.js piece codes to Font Awesome icons
  var pieceToIcon = {
    'p': 'fas fa-chess-pawn',
    'r': 'fas fa-chess-rook',
    'n': 'fas fa-chess-knight',
    'b': 'fas fa-chess-bishop',
    'q': 'fas fa-chess-queen',
    'k': 'fas fa-chess-king'
  };

  var pieceClass = pieceToIcon[piece.charAt(1).toLowerCase()];
  var colorClass = piece.charAt(0) === 'w' ? 'text-white' : 'text-black';
  return `<span class="${pieceClass} ${colorClass}"></span>`;
}

// Configuration object for chessboard.js
var config = {
  draggable: true,
  position: 'start',
  pieceTheme: pieceTheme,
  onDragStart: onDragStart,
  onDrop: onDrop,
  onSnapEnd: onSnapEnd
};

// Initialize the chessboard with the configuration
board = Chessboard('chessboard', config);

// Event listener for drag start
function onDragStart(source, piece, position, orientation) {
  // Don't pick up pieces if the game is over
  if (game.game_over()) return false;

  // Only pick up pieces of the current turn
  if ((game.turn() === 'w' && piece.search(/^b/) !== -1) ||
      (game.turn() === 'b' && piece.search(/^w/) !== -1)) {
    return false;
  }
}

// Event listener for drop
function onDrop(source, target) {
  // Attempt to make a move
  var move = game.move({
    from: source,
    to: target,
    promotion: 'q' // NOTE: Always promote to a queen for simplicity
  });

  // If the move is illegal, return 'snapback' to reset the piece
  if (move === null) return 'snapback';
}

// Event listener for snap end
function onSnapEnd() {
  // Update the board position after the piece snap
  board.position(game.fen());
}
#chessboard {
  width: 400px;
  margin: 20px auto;
}

/* Adjust the size of the font awesome icons to fit the squares */
.chessboard .square-55d63 .piece-417db {
  font-size: 2em; /* Example size, adjust as needed */
}

/* Use !important to enforce color styling on Font Awesome icons */
.fa-chess-pawn, .fa-chess-rook, .fa-chess-knight, .fa-chess-bishop, .fa-chess-queen, .fa-chess-king {
  color: inherit !important;
}

/* Custom color classes for chess pieces */
.text-white { color: white !important; }
.text-black { color: black !important; }
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Chess</title>
    <link rel="stylesheet" href="https://unpkg.com/@chrisoakman/[email protected]/dist/chessboard-1.0.0.min.css">
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/chess.js/0.10.3/chess.min.js"></script>
    <script src="https://unpkg.com/@chrisoakman/[email protected]/dist/chessboard-1.0.0.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">


    <link href="style.css" rel="stylesheet" type="text/css" />
  </head>
<body>
  <div id="chessboard" style="margin: auto;"></div>
  
  <script src="script.js"></script>
</body>
</html>

Can someone tell me how to get the images from chessboard.js library or can someone fix the code I gave above using the awesome font icons. Thank you!

How to collect messages in one box? because the listener can return several for one post

I use gramjs library to access Telegram API.
For example, i publish a new post in channel with 2 images and some description,
but instead of one message (with full info) I receive 2: description + photo and separately another photo.

client.addEventHandler((event) => {
   console.log('new post')
}, new NewMessage({chats: [someId]}))

I found out from the documentation that this is normal and to collect multiple messages into one they use parameters pts and qts (https://core.telegram.org/api/updates), in gramjs there is only pts, which is not very informative

I also found out that you can use a new Album, then similar messages will arrive at once in an array:

client.addEventHandler((event) => {
   console.log('new post')
}, new Album({chats: [someId]}))

But, this dont have any single messages with one photo or just text.
We can use these listeners both, BUT then both listeners will receive these messages with albums, they need to be filtered out somehow in this case from NewMessage listener, otherwise messages will be processed twice from each listener.

How do handle this? Is there any solution with listener?

P.S. I think that the option is to take the identifier when receiving an event and, instead of reading the message, go through the ID to the channel using another method that will return the entire publication.

Described above, I don’t know how to work with updating content in the channel

Attempting to call a API

I currently am running into the issue when I put in the API link for it to be run. Once I go to the console it states it is a await valid in async functions

From what I’ve attempted. I’ve tried to use the common fetch function. I’ve tried to made some adjustments to move over the code on the top of the lines. Error still continues.

const url = 'https://moviesdatabase.p.rapidapi.com/titles/search/keyword/%7Bkeyword%7D';
const options = {
    method: 'GET',
    headers: {
        'X-RapidAPI-Key': '3065ca2efamsh5511818a494e23fp1cbb2cjsna2ae6a53946f',
        'X-RapidAPI-Host': 'moviesdatabase.p.rapidapi.com'
    }
};

try {
    let response = await fetch(url, options);
    const result = await response.text();
    console.log(result);
} catch (error) {
    console.error(error);
}

As soon as I run the console. I get the message: “SyntaxError: await is only valid in async functions, async generators and modules.”

It does appear to be an error on the const result but I am unfamiliar to what I need to do to fix the error.

facing animation bug on canvas

i am trying to create a block mario based game , i am learning i have written some code but i am facing some glitch please help the mario is not standing on the block when i jump please suggest me i am learning when i jump in the block i am facing some bug where i keeps glitching please help here is what i have written please suggest and help


let canvas = document.querySelector('#canvas')
let c = canvas.getContext('2d')

canvas.width = window.innerWidth / 2
canvas.height = window.innerHeight / 2

let marioswy = document.querySelector('#mariosy')
let mariowy = document.querySelector('#marioy')
let gravity = 0.3

let mario = {
    x: 20,
    w: 20,
    h: 40,
    speedX: 0,
    speedY: 10,
    dx: 4,
    dy: -5,
    color: "black",
    canJump: true,
    onGround: true,
}

let block = {
    x: 200,
    y: 280,
    w: 150,
    h: 20,
    color: "black",
    canJump: false,
    onGround: false,
}


mario.y = canvas.height - mario.h;
//-----------------------------------------------------

function animate_mario() {

    c.clearRect(0, 0, canvas.width, canvas.height)

    c.fillRect(mario.x, mario.y, mario.w, mario.h)
    c.fillRect(block.x, block.y, block.w, block.h)
    mario.x += mario.speedX

    if (mario.y + mario.h <= canvas.height) {
        mariowy.textContent = `Y position:  ${mario.y}`
        mario.y += mario.speedY
        mario.speedY += gravity
    }
    else if (
        mario.x < block.x + block.w &&
        mario.x + mario.w > block.x &&
        mario.y < block.y + block.h &&
        mario.y + mario.h > block.y
    ) {
        mario.y = block.y - mario.h;
        mario.dy = 0;
        mario.onGround = true
        gravity = true
    }

    else {
        mario.canJump = true
        mario.onGround = true
        mario.y = canvas.height - mario.h
        mario.speedY = 0;
        //DEBUG
        marioswy.textContent = `X position:  ${mario.x}`
    }
    requestAnimationFrame(animate_mario)
}

animate_mario()
document.addEventListener("keydown", (event) => {
    if (event.key === "ArrowRight") {
        mario.speedX = mario.dx

    }
    if (event.key == "ArrowLeft") {
        mario.speedX = -mario.dx
    }
})

document.addEventListener("keyup", (event) => {
    if (event.key === "ArrowRight") {
        mario.speedX = 0
    }
    if (event.key == "ArrowLeft") {
        mario.speedX = 0
    }
})

//ADDED FOR DEBUGGING 
let aupcount = 0
let aup = document.querySelector('#aup')

//UP DOWN FUCNTIONS
document.addEventListener("keydown", (event) => {
    if (event.key === "ArrowUp" && mario.onGround && mario.canJump) {
        //FOR DEBUG
        aupcount++
        aup.textContent = `Arrow key count :${aupcount}`
        //-------------------------------------------------------
        mario.speedY = mario.dy
        mario.onGround = false
        mario.canJump = false
    }
});

document.addEventListener("keyup", (event) => {
    if (event.key === "ArrowUp") {
        mario.speedY = 0
    }
})

Socket io – method for handling users on the server

In my application, I store users in my database. I’m implementing a messaging system using Socket Io and node, and I’m trying to create a method to efficiently handle users.

The goal is be able to send a message/event to a specific user (using their socket id). This user should be connected to the socket server as soon as they initially load the application.

Here are the two options to solve this problem:

Option 1:

var users = []

io.on('connection', (socket) > {
   // Push user to array when connecting (include their user id as well as socket id)
   users.push({userId: 'ID FROM DB', socketId: socket.id})
})

This option stores all users in an array on the server with their corresponding Id and socket id. This means when sending a message to a user, the following code would be run:

// find user to send event to by searching existing array of user objects
let user = users.find((u) => u.userId = uid)
// send message to specific user
socket.to(user.userId).emit("send message", data)

Option 2:

io.on('connection', (socket) > {
   // Join a room with the name of the users unique id. User id would be passed in from the client
   socket.join(userId)
})

With option 2, no array is required to store users, instead they join a room with their own unique user id as soon as they connect.

When sending a message to a specific user, the code would look like the following for this option.

// Send to users personal room with the name being their user Id
io.to(userId).emit("send message", data)

Is there any issues with each of these options. Is one perhaps inefficient compared to the other? With option 2, could there be the possibility of having too many rooms, and could option 1 be problematic due to the size of the array becoming incredibly large if dozens of users connect to the server? Thanks.

How do I adjust Multer to hold off on saving an image until after successfully completing the database entry using Mongoose?

The usual Multer setup saves files right away, as shown in the basic example below:

const multer = require('multer');
const upload = multer({ dest: 'uploads/' });

const app = express();

app.post('/profile', upload.single('avatar'), function (req, res, next) {
  // req.file is the `avatar` file
  // req.body will hold the text fields, if there were any
  // my database-related code... 
});

When implementing this code, the image is still saved to the upload folder if an error occurs during the database entry process. I aim to ensure the image is saved only when the database entry succeeds. How can I achieve this?