Error: Module Not Found on Discord Bot’s Command Handler

first and foremost, I’m very new to this. I’ve been following the tutorials at the Discord.js Site, with the goal being to make a discord bot for the Play by Post DnD server I’m in where everyone wants to gain experience via word count.

I mention I’m new to this because this is my first hands-on experience with Javascript, a lot of the terminology goes over my head.

So, the problem seems to be where I’ve broken away from the tutorial. It goes over command handlers, which I want to stick with because it seems to be good practice and easier to work with down the line when something most breaks (And I know it will). But the tutorial for Databases (Currency/Sequelizer) doesn’t really touch on command handlers beyond “Maintain references”.

But that’s enough foreword, the problem is in trying to get a command that checks the database for a player’s current experience points and level.

I have the relevant (seemingly) files organized with the index.js and dbObjects.js together, a models folder for the Users, and LevelUp(CurrencyShop in the tutorial) and a separate folder for the Commands like the problematic one, xpcheck.js

I can get the command to function without breaking, using the following,

const { Client, Collection, Formatters, Intents } = require('discord.js');
const { SlashCommandBuilder } = require('@discordjs/builders');
const experience = new  Collection();
const level = new Collection();

Reflect.defineProperty(experience, 'getBalance', {
    /* eslint-disable-next-line func-name-matching */
    value: function getBalance(id) {
        const user = experience.get(id);
        return user ? user.balance : 0;
    },
});

Reflect.defineProperty(level, 'getBalance', {
    /* eslint-disable-next-line func-name-matching */
    value: function getBalance(id) {
        const user = level.get(id);
        return user ? user.balance : 1;
    },
});

module.exports = {
    data: new SlashCommandBuilder()
        .setName('xpcheck')
        .setDescription('Your current Experience and Level'),
    async execute(interaction) {
        const target = interaction.options.getUser('user') ?? interaction.user;

        return interaction.reply(`${target.tag} is level ${level.getBalance(target.id)} and has ${experience.getBalance(target.id)} experience.`);;
    },
};

The problem is that the command doesn’t reference the database. It returns default values (1st level, 0 exp) every time.

I tried getting the command to reference the database, one of many attempts being this one;

const { Client, Collection, Formatters, Intents } = require('discord.js');
const { SlashCommandBuilder } = require('@discordjs/builders');
const Sequelize = require('sequelize');
const { Users, LevelUp } = require('./DiscordBot/dbObjects.js');


module.exports = {
    data: new SlashCommandBuilder()
        .setName('xpcheck')
        .setDescription('Your current Experience and Level'),
    async execute(interaction) {
        const experience = new  Collection();
        const level = new Collection();
        const target = interaction.options.getUser('user') ?? interaction.user;

        return interaction.reply(`${target.tag} is level ${level.getBalance(target.id)} and has ${experience.getBalance(target.id)} experience.`);;
    },
};

However, when I run node deploy-commands.js, it produces

Error: Cannot find module ‘./DiscordBot/dbObjects.js’

It does the same thing even if I remove the /DiscordBot, or any other way I’ve attempted to make a constant for it. I’m really uncertain what I should do to alleviate this issue, and I already know I have a lot of other hurdles to get through (like making the bot count words and award experience for word count). In my attempts to maintain motivation for learning something complicated like this- I thank you for any help, guidance, constructive criticism or advice on good practices you can provide. Thank you.

How to handle input from a textbox to not print a NaN

I am trying to get user input from the textbox and then click the button beside in order to calculate the area of a circle. Problem is alert always prints NaN.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>HTML 5 Boilerplate</title>
    <link rel="stylesheet" href="./css/style.css">
    <script>
        const PI = 3.14159;

        function getAreaOfCircle(rad) {
            let area = PI * Math.pow(rad, 2);
            alert(area);
        }
    </script>
</head>
<body>
    <input type="text" placeholder="Type something..." id="myInput">
    <input type="button" onclick="getAreaOfCircle();" value="Calculate Area of a Circle">
</body>
</html>

Perform different actions in top 3 values in Dictionary?

I have a sorted dictionary with certain number of entries:

dict = {B:3, A:2, C:2, D:1, E:0, F:0...}

After filtering the dictionary to get only the entries with top 3 largest values:

result = Object.fromEntries(Object
    .entries(dict)
    .sort(([, a], [, b]) => b - a)                         
    .filter((s => ([, v]) => s.add(v).size <= 3)(new Set))
);

The current dictionary is

{"B": 3, "A": 2, "C": 2, "D": 1}

So I am trying to add 4 to the largest values,2 to the second largest values and 1 to the third largest values, what are the ways to do this?

One of the ways I can think of is:

for (const key of Object.keys(result)) {
     // if result[key] largest
            //plus 4
     // if result[key] second largest
            //plus 2
     // else
            //plus 1 
}

Thanks for reading..

Why do Tooltips disappear when creating/destroy/creating a graph in Antv/G6

I am working with Vue 3 and antv/G6, and have an issue with tooltips disappearing when I draw a graph (with tooltips), destroy the graph, and redraw it. Here is a minimal working example. I only show the Vue code. I can provide the javascript code to manipulate the graph as well if needed. Any insights are appreciated.

<template>
  <div>
    <h2>Hello World</h2>
    <div id="mountGraph"></div>
  </div>
</template>

<script>
import * as dp from "../Composition/delayPropagationGraphImpl.js";
import G6 from "@antv/g6";
import { onMounted } from "vue";

export default {
  setup() {
    let graphCreated = false;
    let graph = false;

    const graphConfiguration = dp.setupConfiguration({
      container: "mountGraph",
      width: "800",
      height: "600",
      defaultNodeSize: 40,
    });

    function drawGraph() {
      const gNodes = [{ id: "1" }, { id: "2" }, { id: "3" }];
      const gEdges = [
        { source: "1", target: "2" },
        { source: "1", target: "3" },
      ];

      if (graphCreated) {
        graph.destroy();
      }
      graph = new G6.Graph(graphConfiguration); // ERROR
      graphCreated = true;

      const data = { nodes: gNodes, edges: gEdges };
      graph.data(data); // combines data and render
      graph.render();    
      return;
    }

    onMounted(() => {
      drawGraph();
      drawGraph();  // <<< Tooltiops disappear
    });
  },
};
</script>

Using the navigator.share() api, how do I share only the information for one object?

In the snippet below, I’m trying to use the navigator.share() API on a series of articles displaying with a tagged template literal. The problem is that when I click on the share button, all the elements of each object are shared.

I think the problem comes down to this snippet here:

const shareData = {
  title: "example.com",
  text: blogArticles.map((titles) => titles.title),
  url: blogArticles.map((urls) => urls.url)
};

How do I share only the object’s key:value pair for the article shared and not all of the object elements?

const blogArticles = [
  {
    date: "11/24/2021",
    title: "the querySelectorAll DOM API",
    minutesToRead: 10,
    tags: ["javascript", "html"],
    image: "https://placekitten.com/1600/900",
    altText: "image of kittens",
    teaser:
      "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
    url: "articles/queryselectorall-dom-api.html"
  },
  {
    date: "11/24/2021",
    title: "the difference between named and anonymous functions",
    minutesToRead: 10,
    tags: ["javascript", "html"],
    image: "https://placekitten.com/1601/900",
    altText: "image of kittens",
    teaser:
      "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
    url: "articles/difference-between-named-and-anonymous-functions.html"
  },
  {
    date: "11/24/2021",
    title: "css animations explained",
    minutesToRead: 10,
    tags: ["javascript", "html"],
    image: "https://placekitten.com/1602/900",
    altText: "image of kittens",
    teaser:
      "Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus blanditiis magni natus! Blanditiis quibusdam mod",
    url: "articles/css-animations-explained.html"
  }
];

//pass blogArticles data
function blogArticlesTemplate(articles) {
  return `
    <div class="tease-post">
      <div class="tease-post__container">
        <h5 class="tease-post__meta">
          <span class="tease-post__meta--date">${articles.date}</span>
        </h5>
        <h2 class="tease-post__title"><a href="${articles.url}">${articles.title}</a></h2>
        <div class="tease-post__details">
          <h4><i class="fa fa-clock"></i> ${articles.minutesToRead} minute read</h4>
          <h4><i class="fa fa-tag"></i> ${articles.tags}</h4>
          <h4 class="share"><i class="fa fa-share-alt"></i> Share</h4>
        </div>
        <hr>
        <img class="tease-post__img" src="${articles.image}" alt="${articles.altText}">
        <div class="tease-post__text">
          <p>${articles.teaser}</p>

          <a href="//${articles.url}" class="tease-post__more">[read more]</a>
        </div>      
      </div>
    </div>    
  `;
}

document.getElementById('blogTeaserList').innerHTML = `
  ${blogArticles.map(blogArticlesTemplate).join('')}
  `;

//sharing
const shareData = {
  title: "example.com",
  text: blogArticles.map((titles) => titles.title),
  url: blogArticles.map((urls) => urls.url)
};

const shareButtons = document.querySelectorAll(".share");

if ("share" in navigator) {
  shareButtons.forEach((shareButton) => {
    shareButton.addEventListener("click", () => {
      navigator
        .share(shareData)
        .then(() => {
          console.log("Shared", shareData);
        })
        .catch(console.error);
    });
  });
} else {
  shareButtons.forEach((shareButton) => {
    shareButton.style.display = "none";
  });
}
img {
  width: 100%;
  height: auto;
}

.tease-post {
  max-width: 350px;
  background: lightgray;
}

.share {
  cursor: pointer;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
<div id="blogTeaserList"></div>

replace the form with a message -not with PHP

I have this code

<!DOCTYPE html>
<html>
<body>

<p>This example demonstrates how to assign an "onsubmit" event to a form element.</p>

<p>When you submit the form, a function is triggered which alerts some text.</p>

<form action="/action_page.php" onsubmit="myFunction()">
  Enter name: <input type="text" name="fname">
  <input type="submit" value="Submit">
</form>

<script>
function myFunction() {
  alert("the message has been send");
}
</script>

</body>
</html>

I want not to do this alert message.I want to replace the form giving it this message the message has been send

Vue cli build show blank page – Apache server

I have some problem with vue cli. When I run npm run serve everything went smooth. When I go for dev mode, npm run build-dev, the build process completed. I got a blank page.

The error message is “Uncaught SyntaxError: Unexpected token ‘<‘”

Below is my setup:
pacakge.json

{
  "name": "gold",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "test:unit": "vue-cli-service test:unit",
    "lint": "vue-cli-service lint",
    "build-dev": "vue-cli-service build --mode production-dev",
    "build-production": "vue-cli-service build"
  },
  "dependencies": {
    "axios": "^0.21.1",
    "babel-polyfill": "^6.26.0",
    "camelize2": "^1.0.0",
    "core-js": "^3.6.5",
    "element-ui": "^2.15.5",
    "vue": "^2.6.14",
    "vue-carousel": "^0.18.0",
    "vue-router": "^3.2.0",
    "vuex": "^3.4.0"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-router": "~4.5.0",
    "@vue/cli-plugin-unit-jest": "~4.5.0",
    "@vue/cli-plugin-vuex": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/eslint-config-standard": "^5.1.2",
    "@vue/test-utils": "^1.0.3",
    "babel-eslint": "^10.1.0",
    "babel-plugin-component": "^1.1.1",
    "eslint": "^6.8.0",
    "eslint-plugin-import": "^2.20.2",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.0",
    "eslint-plugin-vue": "^6.2.2",
    "sass": "^1.26.5",
    "sass-loader": "^8.0.2",
    "vue-template-compiler": "^2.6.14",
    "webpack-bundle-analyzer": "^3.9.0"
  }
}

vue.config.js

// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
//   .BundleAnalyzerPlugin

module.exports = {
  // options...
  // configureWebpack: {
  //   plugins: [new BundleAnalyzerPlugin()]
  // },
  // configureWebpack: {
  //   optimization: {
  //     runtimeChunk: 'single',
  //     splitChunks: {
  //       chunks: 'all',
  //       maxInitialRequests: Infinity,
  //       minSize: 0,
  //       cacheGroups: {
  //         vendor: {
  //           test: /[\/]node_modules[\/]/,
  //           name(module) {
  //             // get the name. E.g. node_modules/packageName/not/this/part.js
  //             // or node_modules/packageName
  //             const packageName = module.context.match(
  //               /[\/]node_modules[\/](.*?)([\/]|$)/
  //             )[1]

  //             // npm package names are URL-safe, but some servers don't like @ symbols
  //             return `npm.${packageName.replace('@', '')}`
  //           }
  //         }
  //       }
  //     }
  //   }
  // },
  devServer: {
    port: 8989
  },
  transpileDependencies: ['camelcase']
}

Sorry before if I can not show any further code, thanks.

Google Apps Script: Save Gmail attachment to SHARED Google Drive

Goal:
Update code below to save attachments to a “Test” folder within “Shared drive”

So far I’ve been successful in saving attachments to “My Drive” using the gmail2gdrive script found on https://github.com/ahochsteger/gmail2gdrive

This script uses DriveApp.getRootFolder() to find the root folder, but does not look at shared drives.
I have the “Drive” Advanced Service set up and am able to at least view up to 10 folders in the Shared Drive using getSharedDrives(), but have been unsuccessful updating the code to transfer files to a shared drives.

PROTOCOL_ENQUEUE_AFTER_FATAL_ERROR On Certain Hour

I have a problem about connecting to MySQL. After 8 PM (My local time), the connection is lost. So I modified my code, whenever mysql throw PROTOCOL_CONNECTION_LOST, it will try to reconnect to the mysql. The error for PROTOCOL_CONNECTION_LOST is gone, but it give new error code PROTOCOL_ENQUEUE_AFTER_FATAL_ERROR when trying to connect to the server.
This is my code to create connection to MySQL.

const dbConn = mysql.createConnection({
    host        : 'localhost',
    user        : 'xxxx',
    password    : 'xxxx',
    database    : 'test'
});

function handleDisconnect() {

  dbConn.connect(function(err, connection) {             
    if(err) {                                     
      console.log('error when connecting to db:', err);
      setTimeout(handleDisconnect, 2000); 
    }       
  });                                     
   
  dbConn.on('error', function(err) {
    console.log('db error', err);
    if(err.code === 'PROTOCOL_CONNECTION_LOST') { 
      handleDisconnect();                         
    } else {                                     
      throw(err)                       
    }
  });
}

handleDisconnect();
module.exports = dbConn;

This is my error stack

0|index    | error when connecting to db: Error: Cannot enqueue Handshake after fatal error.
0|index    |     at Protocol._validateEnqueue (/home/mydev/SOBATku/node_modules/mysql/lib/protocol/Protocol.js:212:16)
0|index    |     at Protocol._enqueue (/home/mydev/SOBATku/node_modules/mysql/lib/protocol/Protocol.js:138:13)
0|index    |     at Protocol.handshake (/home/mydev/SOBATku/node_modules/mysql/lib/protocol/Protocol.js:51:23)
0|index    |     at Connection.connect (/home/mydev/SOBATku/node_modules/mysql/lib/Connection.js:116:18)
0|index    |     at handleDisconnect (/home/mydev/SOBATku/config/db.config.js:34:10)
0|index    |     at Connection.<anonymous> (/home/mydev/SOBATku/config/db.config.js:45:7)
0|index    |     at Connection.emit (node:events:390:28)
0|index    |     at Connection._handleProtocolError (/home/mydev/SOBATku/node_modules/mysql/lib/Connection.js:423:8)
0|index    |     at Protocol.emit (node:events:390:28)
0|index    |     at Protocol._delegateError (/home/mydev/SOBATku/node_modules/mysql/lib/protocol/Protocol.js:398:10) {
0|index    |   code: 'PROTOCOL_ENQUEUE_AFTER_FATAL_ERROR',
0|index    |   fatal: false
0|index    | }

It can reconnect when I do some command like pm2 logs or other command with pm2 (I use pm2 for the node run command). Planning to use cron function to restart my server every 8PM, but if it can solved without restart the server, it will be very helpful. Thank you.

why does Echoing php into JavaScript not work

I am trying to echo a multidimensional array from PHP to js, but it is giving me an error saying that “<” is an unexpected token.

js

var products = <?php echo json_encode( $products ) ?>;

Php

<?php
    // PHP array
    $products = array(
        // product abbreviation, product name, unit price
        array('choc_cake', 'Chocolate Cake', 15),
        array('carrot_cake', 'Carrot Cake', 12),
        array('cheese_cake', 'Cheese Cake', 20),
        array('banana_bread', 'Banana Bread', 14)
    );
?>

Implementing a nested mutation based on a relationship between two GraphQL types

I want to create a form that allows me to create a value from a nested field. Root values in the same mutation work ok, but when I want to create the nested value, I cannot. Take for instance the below mutation.

export const createPremise = (newPremiseEntry) => {
  const mutation = gql`
    mutation CreatePremise($input: PremiseInput!) {
      createPremise(data: $input) {
        _id
        _ts
        content
      
        createdAt
      }
    }
  `
  return graphQLClient.request(mutation, { input: newPremiseEntry })
}

I want to create a premise with the root value content on my form, so, on my frontend I have:

const ENTRIES_PATH = '/api/entries/allPremises'

    const putPremiseEntry = (payload) =>
        fetch(ENTRIES_PATH, {
            method: 'POST',
            body: JSON.stringify(payload),
            headers: {
                'Content-Type': 'application/json',
            },
        }).then((res) => (res.ok ? res.json() : Promise.reject(res)))

Then I do this:

const useEntriesFlow = () => {
    const onSubmit = async (payload) => {
        await putPremiseEntry(payload)
        await mutate(ENTRIES_PATH)
    }
    return {
        onSubmit,
    }
}

const EntryPremiseForm = ({ onSubmit: onSubmitProp }, storyId) => {
    const [show, setShow] = useState(false);

    const handleClose = () => setShow(false);
    const handleShow = () => setShow(true);
    const initial = {
        content: '', // My premise has a field called content, which I want to input, remember this, i'll come back to it.

    }
    const [values, setValues] = useState(initial)
    const [formState, setFormState] = useState('initial')
    const isSubmitting = formState === 'submitting'

    const onSubmit = (ev) => {
        ev.preventDefault()
        setFormState('submitting')
        onSubmitProp(values)
            .then(() => {
                setValues(initial)
                setFormState('submitted')
            })
            .catch(() => {
                setFormState('failed')
            })
    }
    const makeOnChange =
        (fieldName) =>
            ({ target: { value } }) =>
                setValues({
                    ...values,
                    [fieldName]: value,
                })
    return (
        <>
                <form className="" onSubmit={onSubmit}>
                        <input  //this is my input for creating the premise
                            required
                            className={cn(inputClasses, '')}
                            aria-label="premise"
                            placeholder="Premise"
                            value={values.content}
                            onChange={makeOnChange('content')} // On my form, I add the `content` value which goes into my premise object, creating the premise.
                        />
                        <Button type="submit" disabled={isSubmitting}>
                            {isSubmitting ? <LoadingSpinner /> : 'Create Story'}
                        </Button>
                </form>
                {{
                    failed: () => <ErrorMessage>Something went wrong. :(</ErrorMessage>,
                    submitted: () => ( <SuccessMessage>Thanks for signing the guestbook.</SuccessMessage>
                    ),
                }[formState]?.()}
        </>
    )
}

This is all fine, It works.

THE PROBLEM

The problem comes when I need to do the same thing, but with an extra field that is nested. This type Premise belongs to another object called Story

type Story {
  name: String!
  createdAt: Time!
  premises: [Premise] @relation
}

type Premise {
  content: String!
  belongs: Story!
  createdAt: Time!
}

belongs is how faunadb creates the relation

The mutation looks like this:

export const createPremise = (newPremiseEntry) => {
  const mutation = gql`
    mutation CreatePremise($input: PremiseInput!) {
      createPremise(data: $input) {
        _id
        _ts
        content
        belongs{name}  //nested relationship, not sure if syntax is correct.
        createdAt
      }
    }
  `
  return graphQLClient.request(mutation, { input: newPremiseEntry })
}

The difference being:

belongs{name}

name being the name of the story it belongs to. found on the type Story

FIRST PROBLEM

How do I represent this in my POST?

export default async function handler(req, res) {
  const handlers = {

    POST: async () => {
      const {
        body: { 
        content, 
        belongs{name} // ?? WHAT DO I PUT HERE? HOW DO I REPRESENT BELONGS.NAME AS SEEN IN TYPE PREMISE?
        },
      } = req
      const createdPremise = await createPremise({
        content, belongs{name}, //???
        createdAt: new Date(),
      })
      res.json(createdPremise)
    },
  }

  if (!handlers[req.method]) {
    return res.status(405).end()
  }

  await handlers[req.method]()
}

SECOND PROBLEM

In my const EntryPremiseForm above how do I represent that belongs.name

const handleClose = () => setShow(false);
    const handleShow = () => setShow(true);
    const initial = {
        content: '',
        belongs.name: '', //??? How do I set the inital state for this nested relationship field. remember, content works fine
    }

When I have that, I can then do this

<input  
      required
      className={cn(inputClasses, '')}
      aria-label="premise"
      placeholder="Premise"
      value={values.belongs.name} // ??? HOW DO I REPRESENT THAT HERE
      onChange={makeOnChange('values.belongs.name')} //???
/>

Any help is greatly apreciated.