remove() not working(as intended) in javascript

I’m just a twelve year old that just got into coding last year, I am starting this specific part of a project that involves the user clicking a button with class: add_button to create a div that is the file for storing information, all the functions in the user created files are functional except for one,

function delete_file() {
    const deleted_file = event.target.parentNode;
    deleted_file.remove();
  }

It turns out during testing, it only deletes the latest div/file that was created, I later made it so that it doesn’t have remove() but instead change the border which works for some reason.The full code is here.
HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>LanguageMaker3000</title>
    <link rel="stylesheet" href="LanguageMaker3000.css">
</head>
<body>
    <script src="LanguageMaker3000.js"></script>
    <section class="top_nav">
        <p class="main_title"><u>LanguageMaker3000</u></p>
        <p class="word"><u>Robosteyr</u></p>
        <p class="wordt"><u>derewaq</u></p>
        <p class="wordg"><u>mmuytr</u></p>
        <p class="wordi"><u>sacter</u></p>
        <p class="wordj"><u>sabbydabby</u></p>
        <p class="wordp"><u>cocou</u></p>
        <p class="words"><u>piuyttt</u></p>
        <input type="text" placeholder="Search Files..." class="folder_searcher">
        <button type="button" class="search_button">Y</button>
        <div class="scroll_image">
            <p class="about_us"><u>About Us</u></p>
            <p class="about_us_paragraph">Hi! I'm Matt and I proudly present the LanguageMaker3000(Although there aren't 2999 more versions of this)!Language has been around for more than 1 million years and
                is the root of every famous civilizations such as Ancient Egypt and Greece.This is a goofy website that allows you to create your own languages!:)
            </p>
        </div>
        <div class="seperator"></div>
    </section>
    <section class="content">
        <div class="add_bar"></div>
        <button class="add_button" onclick="create_file()"><b>+</b></button>
        <p class="num_file_text">Current Files:</p>
        <div class="number_list">
            <div class="number_list_r">
                <p class="starting_num">0</p>
            </div>
        </div>
        <div class="file_query">
        </div>
    </section>
</body>
</html>

CSS:

body {
  overflow-x: hidden;
}
button {
  cursor: pointer;
}
.top_nav {
    position: sticky;
    background-color: mediumspringgreen;
    width: 200pc;
    height: 6pc;
    margin-left: -34px;
    margin-top: -35px;
    border-bottom: 5px solid yellow;
  }
  
.main_title {
    position: relative;
    top: 20px;
    left: 50px;
    color: yellow;
    z-index: 2;
    font-size: 200%;
    font-family: fantasy;
  }
  .word {
    position: relative;
    top: -4pc;
    left: 400px;
    color: yellow;
    z-index: 5;
    font-size: 150%;
    font-family: fantasy;
  }
  .wordt {
    position: relative;
    top: -4pc;
    left: 400px;
    color: yellow;
    z-index: 5;
    font-size: 150%;
    font-family: fantasy;
  }
  .wordg {
    position: relative;
    top: -9pc;
    left: 550px;
    color: yellow;
    z-index: 5;
    font-size: 150%;
    font-family: fantasy;
  }
  .wordi {
    position: relative;
    top: -14pc;
    transform: rotate(2deg);
    left: 700px;
    color: yellow;
    z-index: 5;
    font-size: 150%;
    font-family: fantasy;
    width: 12px;
    transform: rotate(90deg)
  }
  .wordj {
    position: relative;
    top: -15pc;
    left: 900px;
    color: yellow;
    z-index: 5;
    font-size: 150%;
    font-family: fantasy;
  }
  .wordp {
    position: relative;
    top: -20.7pc;
    left: 800px;
    color: yellow;
    z-index: 5;
    font-size: 150%;
    font-family: fantasy;
    width: 12px;
    transform: rotate(90deg)
  }
  .words {
    position: relative;
    top: -24.5pc;
    left: 1050px;
    color: yellow;
    z-index: 5;
    font-size: 150%;
    font-family: fantasy;
    width: 12px;
  }
  .folder_searcher {
    position: relative;
    z-index: 5;
    left: 64pc;
    top: -25.6pc;
    width: 23pc;
    height: 35px;
    border: 3px solid black;
  }
  .search_button_text {
    position: relative;
    top: -29.4pc;
    left: 95.7pc;
    z-index: 2;
    font-size: 90%;
    font-family: fantasy;
  }
  .search_button {
    position: relative;
    top: -25.6pc;
    border-top-right-radius: 25%;
    border-bottom-right-radius: 25%;
    right: -63.5pc;
    background-color: #90ee90;
    width: 50px;
    height: 43px;
    border: 2px solid black;
    cursor: pointer;
  }
.top_nav:hover .search_button {
  background-color: yellowgreen;
}
.scroll_image {
  position: absolute;
  top: 6.4pc;
  height: 193px;
  width: 150pc;
  background-image: linear-gradient(180deg, rgba(107, 87, 88, 0.7), rgba(253, 253, 253, 0.9)), url("https://indianapublicmedia.org/large-images/amos-images/isaiah-scroll.jpg");
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
  overflow:scroll;
}
.seperator {
  margin-top: -12.2pc;
  height: 12px;
  background-image: linear-gradient(90deg, rgba(178, 255, 89, 0.5), rgba(37, 58, 124, 0.5));
}
.about_us {
  color: white;
  font-size: 200%;
  font-family:'Courier New', Courier, monospace;
  margin-left: 45pc;
}
.about_us_paragraph {
  color: white;
  font-size: 200%;
  margin-left: 50px;
  width: 90pc;
  font-family:'Courier New', Courier, monospace;
}
.add_bar {
  margin-top: 13pc;
  margin-left: -12px;
  width: 230pc;
  height: 50px;
  background-color: rgb(233, 232, 232);
  border-bottom: 3px solid grey;
}
.add_button {
  position: relative;
  top: -46px;
  margin-left: 78pc;
  width: 40px;
  height: 40px;
  border-radius: 50%;
}
.content:hover .add_button {
  background-color: grey;
}
.num_file_text {
  position: relative;
  margin-top: -28.5pc;
  top: 23pc;
  color: rgb(14, 204, 204);
  font-size: 150%;
  font-family: 'Courier New', Courier, monospace;
}
.number_list {
  margin-top: 21.5pc;
  margin-left: 13pc;
  width: 350px;
  height: 30px;
  background-color: white;
  border-radius: 12%;
  overflow: hidden;
}
.number_list_r {
  height: 90px;
  padding-top: 1px;
}
.starting_num {
  position: relative;
  top: -12px;
}
.file_query {
  border: 1px solid rgb(214, 212, 212);
  margin-top: 0.8pc;
  margin-left: -12pc;
  width: 250pc;
  height: 290pc;
  background-image: linear-gradient(180deg, rgb(255, 255, 255), rgba(0, 0, 0, 0.5)), url("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTHCBd8-57JaK_VsnXDjo61aL-3AkwM7TpLN-w7-Vaa&s");
  background-repeat: no-repeat;
  background-size: cover;
  background-attachment: fixed;
  background-position: center;
}
.filebase:hover .okbutton {
  background-color: yellowgreen;
}
.filebase:hover .openbutton {
  background-color: yellowgreen;
}
.filebase:hover .deletebutton {
  background-color: yellowgreen;
}
.filebase:hover .renamebutton {
  background-color: yellowgreen;
}
button {
  cursor: pointer;
}

JS:

//Create New File
function create_file() {
  const file_query = document.getElementsByClassName("file_query")[0];
  const file_base = document.createElement("div");
  const file_name = document.createElement("input");
  const ok_button = document.createElement("button");
  const open_button = document.createElement("button");
  const rename_button = document.createElement("button");
  const delete_button = document.createElement("button");
  file_base.setAttribute("style", "margin-left: 28pc; margin-top: 4pc;  width: 66pc;  height: 5pc;  border: 5px outset grey;  background-color: rgb(182, 180, 180);");
  file_base.setAttribute("class", "file_base_t");
  file_name.setAttribute("style", "position: absolute;  margin-top: 1.45pc;  margin-left: 1pc;  height: 30px;  width: 340px;");
  file_name.setAttribute("class", "id_collector");
  file_name.setAttribute("placeholder", "File Name...");
  file_name.addEventListener("input", no_border)
  file_base.appendChild(file_name);
  ok_button.setAttribute("style", "position: absolute;  font-family: fantasy; margin-top: 1.4pc;  margin-left: 22.5pc;  height: 35.5px;  width: 50px;  border-top-right-radius: 25%;  border-bottom-right-radius: 25%;  background-color: #90ee90;");
  ok_button.setAttribute("class", "ok_button_t");
  ok_button.textContent = "Y";
  ok_button.addEventListener("click", addId);
  file_base.appendChild(ok_button);
  open_button.setAttribute("style", "position: absolute;  font-family: fantasy; margin-left: 9pc;  margin-top: 19px;  height: 50px;  width: 70px;  background-color: #90ee90;  display: none;  pointer-events: none;");
  open_button.setAttribute("class", "open_button_t");
  open_button.textContent = "Open";
  open_button.addEventListener("click", open_dictionary); 
  file_base.appendChild(open_button);
  rename_button.setAttribute("style", "position: absolute;  font-family: fantasy; margin-left: 52pc;  margin-top: 17px;  height: 50px;  width: 70px;  background-color: #90ee90;  display: none;  pointer-events: none;");
  rename_button.setAttribute("class", "rename_button_t");
  rename_button.textContent = "Rename";
  rename_button.addEventListener("click", rename_id);
  file_base.appendChild(rename_button);
  delete_button.setAttribute("style", "position: absolute; font-family: fantasy; margin-left: 60pc;width: 70px;height: 50px; margin-top: 16px;  background-color: #90ee90;");
  delete_button.setAttribute("class", "delete_button_t");
  delete_button.textContent = "Delete";
  delete_button.addEventListener("click", delete_file); 
  file_base.appendChild(delete_button);
  file_query.appendChild(file_base);
}

function addId() {
  const id_parent = event.target.parentNode;
  const y_no = id_parent.querySelector(":nth-child(2)")
  const id_input = id_parent.querySelector(":nth-child(1)");
  const open_ok = id_parent.querySelector(":nth-child(3)");
  const rename_ok = id_parent.querySelector(":nth-child(4)");
  let id_value = id_input.value;
  if (id_value == "") {
    id_input.style.border = "3px solid red";
  } else {
    id_parent.setAttribute("id", id_value);
    id_input.style.display = "none";
    id_input.style.pointerEvents = "none";
    y_no.style.display = "none";
    y_no.style.pointerEvents = "none";
    open_ok.style.display = "block";
    open_ok.style.pointerEvents = "auto";
    rename_ok.style.display = "block";
    rename_ok.style.pointerEvents = "auto";
  }
}

function open_dictionary() {
    window.location.replace("http://127.0.0.1:5500/LanguageStorage.html")
}

function rename_id() {
    const renamed_button = event.target.parentNode;
    const open_no = renamed_button.querySelector(":nth-child(3)");
    const rename_no = renamed_button.querySelector(":nth-child(4)");
    const ok_ok = renamed_button.querySelector(":nth-child(2)");
    const input_ok = renamed_button.querySelector(":nth-child(1)");
    open_no.style.display = "none";
    open_no.style.pointerEvents = "none";
    rename_no.style.display = "none";
    rename_no.style.pointerEvents = "none";
    ok_ok.style.display = "block";
    ok_ok.style.pointerEvents = "auto";
    input_ok.style.display = "block";
    input_ok.style.pointerEvents = "auto";
}

function delete_file() {
    const deleted_file = event.target.parentNode;
    deleted_file.remove();
  }
  
function no_border() {
    event.target.parentNode.querySelector(":nth-child(1)").style.border = "none";
}

I will be happy to accept any solutions/alternatives to my issue.Thx.

…………………………………………………………………………………….

JavaScript audio frequency change

I need a react JavaScript function which takes a frequency and audio file and it’s should change frequency of audio file and play it.
Please someone guide me.

function changefrequencyandplay(file,frequency){
//perform action

}

The select2 won’t selected data

i have a lil problem with my select2 when in edit data, the select2 won’t selected the value
This is my data show table data, and when i clicked on edit data button, it should selected “settings” on the parent’s value, but it’s not working see this

This is my ajax script, fetching data when click the edit button i usually use the trigger to set the selected value for the select2 but it’s not working, and this is my controller.

the data is show but not selected, it’s should be like this

I don’t know whether the way I wrote the code is correct or not, i new on code, so help me please 🙂

How to retrieve attribute name for custom widget in Thingsboard with Angular?

I am trying to retrieve an attribute name in HTML by calling a javascript in scope function called AttributeName however I keep being returned ctx.AttributeName is not a function in the widget window. I thought that this is because the html is being loaded first before the javascript, so I added ng-if="AttributeName" in the html however no luck. What am I doing wrong here?

My JS and Angular knowledge is limited and I come from a C/C++ background. Trying to do and learn as much as I can until we find a good JS dev.

HTML where I am calling AttributeName

    <thead ng-if="AttributeName">
        <tr>
            <th colspan="4">{{ AttributeName(0) }}</th>
        </tr>
    </thead>

Javascript

self.onInit = function() {

    var $scope = self.ctx.$scope;
    $scope.AttributeName = function(index) {
        return $scope.ctx.data[0].datasource.name;
    };
}

Using:

  • ThingsBoard: 3.5.1

Hey, my post of private route was deleted

I’m stuck in a issue for 3days , I already did a post about it and they told me to see some posts but I didn’t find my answer , I’m creating a protectedRoutes but I can always go to them even without token this is my code thank you.

function App() {
  return (
    <Routes>
        <Route
          path='/'
          element={
          <ProtectedRoute>
            <SharedLayout />
          </ProtectedRoute>}
        >
          <Route index element={<Stats />} />
          <Route path='all-jobs' element={<AllJobs />} />
          <Route path='add-job' element={<AddJob />} />
          <Route path='profile' element={<Profile />} />
        </Route>
        <Route path='landing' element={<Landing />} />
        <Route path='register' element={<Register />} />
        <Route path='*' element={<Error />} />
      </Routes>
  );
}

ProtectRoute.js
export default function ProtectedRoute({ children}) {
  const [cookies] = useCookies(["token"]);

  if(!cookies.token) {
    return <Navigate to="/landing" />;
  }

  return children;
}

Nav.js
  const handleLogout = () => {
    removeCookie('name')
    removeCookie('token');
    navigate('/landing');
  };
...
<button onClick={() => {handleLogout()}}>Logout</button>

Register.js
...
if (isLogin) {
        // Login
        const response = await axios.post("/auth/login", {
          email: inputs.email,
          password: inputs.password,
        });
        setUser(response.data.user);
        const token = response.data?.user.token;
        setCookie("token", token, {
          path: "/",
        });

Issue with Displaying Chatbot Replies in Python and JavaScript Implementation

Description:

I am facing an issue with displaying chatbot replies in my Python and JavaScript implementation. I followed a YouTube tutorial to create a chatbot using Flask, Python, and JavaScript. The chatbot user interface (UI) appears correctly, and I can enter messages and send them. However, the chatbot’s replies are not being displayed in the chatbox.

Here is the relevant code:

app.py:

from flask import Flask, render_template, request, jsonify

from chat import get_response

app = Flask(__name__)

@app.get("/")
def index_get():
    return render_template("base.html")

@app.post("/predict")
def predict():
   text = request.get_json().get("message")
   # TO-DO: check if text is valid
   response = get_response(text)
   message = {"answer": response}
   return jsonify(message)

if __name__ == "__main__":
    app.run(debug=True, port=5001)

app.js:

class Chatbox {
  constructor() {
    this.args = {
      openButton: document.querySelector(".chatbox__button"),
      sendButton: document.querySelector(".send__button"),
    };

    this.state = false;
    this.messages = [];
  }

  toggleState(chatBox) {
    chatBox.classList.toggle("chatbox--active");
  }

  onSendButton(chatBox) {
    var textField = chatBox.querySelector("input");
    let text1 = textField.value;
    if (text1 === "") {
      return;
    }

    let msg1 = { name: "User", message: text1 };
    this.messages.push(msg1);

    fetch($SCRIPT_ROOT + "/predict", {
      method: "POST",
      body: JSON.stringify({ message: text1 }),
      mode: "cors",
      headers: {
        "Content-Type": "application/json",
      },
    })
      .then((r) => r.json())
      .then((r) => {
        let msg2 = { name: "Sam", message: r.answer };
        this.messages.push(msg2);
        this.updateChatText(chatBox);
        textField.value = "";
      })
      .catch((error) => {
        console.error("Error:", error);
        this.updateChatText(chatBox);
        textField.value = "";
      });
  }

  updateChatText(chatBox) {
    var html = "";
    this.messages
      .slice()
      .reverse()
      .forEach(function (item, index) {
        if (item.name === "Sam") {
          html +=
            '<div class="messages__item messages__item--visitor">' +
            item.message +
            "</div>";
        } else {
          html +=
            '<div class="messages__item messages__item--operator">' +
            item.message +
            "</div>";
        }
      });

    const chatMessage = chatBox.querySelector(".chatbox__messages");
    chatMessage.innerHTML = html;
  }

  display() {
    const { openButton, sendButton } = this.args;
    const chatBox = document.querySelector(".chatbox__support");

    openButton.addEventListener("click", () => this.toggleState(chatBox));

    sendButton.addEventListener("click", () => this.onSendButton(chatBox));

    const inputNode = chatBox.querySelector("input");
    inputNode.addEventListener("keyup", (event) => {
      if (event.key === "Enter") {
        this.onSendButton(chatBox);
      }
    });
  }
}

const chatbox = new Chatbox();
chatbox.display();

base.html:

<!DOCTYPE html>
<html lang="en">
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">

<head>
    <meta charset="UTF-8">
    <title>Chatbot</title>
</head>
<body>
<div class="container">
    <div class="chatbox">
        <div class="chatbox__support">
            <!-- Chatbox content -->
        </div>
        <div class="chatbox__button">
            <!-- Chatbox button -->
        </div>
    </div>
</div>

<script>
    var $SCRIPT_ROOT = "{{ request.script_root }}";
</script>
<script type="text/javascript" src="{{ url_for('static', filename='app.js') }}"></script>

</body>
</html>

style.css:

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: "Nunito", sans-serif;
  font-weight: 400;
  font-size: 100%;
  background: #f1f1f1;
}

*,
html {
  --primaryGradient: linear-gradient(93.12deg, #581b98 0.52%, #9c1de7 100%);
  --secondaryGradient: linear-gradient(
    268.91deg,
    #581b98 -2.14%,
    #9c1de7 99.69%
  );
  --primaryBoxShadow: 0px 10px 15px rgba(0, 0, 0, 0.1);
  --secondaryBoxShadow: 0px -10px 15px rgba(0, 0, 0, 0.1);
  --primary: #581b98;
}

/* CHATBOX
=============== */
.chatbox {
  position: absolute;
  bottom: 30px;
  right: 30px;
}

/* CONTENT IS CLOSE */
.chatbox__support {
  display: flex;
  flex-direction: column;
  background: #eee;
  width: 300px;
  height: 350px;
  z-index: -123456;
  opacity: 0;
  transition: all 0.5s ease-in-out;
}

/* CONTENT ISOPEN */
.chatbox--active {
  transform: translateY(-40px);
  z-index: 123456;
  opacity: 1;
}

/* BUTTON */
.chatbox__button {
  text-align: right;
}

.send__button {
  padding: 6px;
  background: transparent;
  border: none;
  outline: none;
  cursor: pointer;
}

/* HEADER */
.chatbox__header {
  position: sticky;
  top: 0;
  background: orange;
}

/* MESSAGES */
.chatbox__messages {
  margin-top: auto;
  display: flex;
  overflow-y: scroll;
  flex-direction: column-reverse;
}

.messages__item {
  background: orange;
  max-width: 60.6%;
  width: fit-content;
}

.messages__item--operator {
  margin-left: auto;
}

.messages__item--visitor {
  margin-right: auto;
}

/* FOOTER */
.chatbox__footer {
  position: sticky;
  bottom: 0;
}

.chatbox__support {
  background: #f9f9f9;
  height: 450px;
  width: 350px;
  box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.1);
  border-top-left-radius: 20px;
  border-top-right-radius: 20px;
}

/* HEADER */
.chatbox__header {
  background: var(--primaryGradient);
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  padding: 15px 20px;
  border-top-left-radius: 20px;
  border-top-right-radius: 20px;
  box-shadow: var(--primaryBoxShadow);
}

.chatbox__image--header {
  margin-right: 10px;
}

.chatbox__heading--header {
  font-size: 1.2rem;
  color: white;
}

.chatbox__description--header {
  font-size: 0.9rem;
  color: white;
}

/* Messages */
.chatbox__messages {
  padding: 0 20px;
}

.messages__item {
  margin-top: 10px;
  background: #e0e0e0;
  padding: 8px 12px;
  max-width: 70%;
}

.messages__item--visitor,
.messages__item--typing {
  border-top-left-radius: 20px;
  border-top-right-radius: 20px;
  border-bottom-right-radius: 20px;
}

.messages__item--operator {
  border-top-left-radius: 20px;
  border-top-right-radius: 20px;
  border-bottom-left-radius: 20px;
  background: var(--primary);
  color: white;
}

/* FOOTER */
.chatbox__footer {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  padding: 20px 20px;
  background: var(--secondaryGradient);
  box-shadow: var(--secondaryBoxShadow);
  border-bottom-right-radius: 10px;
  border-bottom-left-radius: 10px;
  margin-top: 20px;
}

.chatbox__footer input {
  width: 80%;
  border: none;
  padding: 10px 10px;
  border-radius: 30px;
  text-align: left;
}

.chatbox__send--footer {
  color: white;
}

.chatbox__button button,
.chatbox__button button:focus,
.chatbox__button button:visited {
  padding: 10px;
  background: white;
  border: none;
  outline: none;
  border-top-left-radius: 50px;
  border-top-right-radius: 50px;
  border-bottom-left-radius: 50px;
  box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1);
  cursor: pointer;
}

I received assistance earlier in this post:

“https://stackoverflow.com/questions/76601464/send-button-on-chatbot-does-not-work-once-clicked?noredirect=1#comment135071618_76601464”

where it was suggested to remove the |tojson filter from $SCRIPT_ROOT in the JavaScript code. After making this change, the user’s messages are displayed correctly. However, the chatbot’s replies are still not appearing in the chatbox.

I would appreciate any guidance or suggestions to resolve this issue. Thank you!

Nodemailer -No recipients defined only at React Vite project

i hope everyone is doing fine!

Im here asking for help on a weird or at least an issue that i dont know how to solve it for the moment . Im using react to create a web page where i want to have a contact form page using nodemailer , after i did all the setup required and started my server i see this issue :
Error Error: No recipients defined

Well after that i went and check all the configuration again a few times , also check my .env file and the OAuth2 configuration that im using . After confirming that for me everything was fine i tried with an empty javascript project (no react) and created a new server file , and boom the code works as it should , i receive the email , etc . So now im stuck on finding why the code works on an empty javascript project and not on a react project . The code look like this :

Javascript :

const express = require("express");
const nodemailer = require("nodemailer");
const app = express();
require("dotenv").config();

const port = 3000;
app.listen(port, () => {
  console.log(`Server is running on port: ${port}`);
});

let transporter = nodemailer.createTransport({
  service: "gmail",
  auth: {
    type: "OAuth2",
    user: process.env.EMAIL,
    pass: process.env.WORD,
    clientId: process.env.OAUTH_CLIENTID,
    clientSecret: process.env.OAUTH_CLIENT_SECRET,
    refreshToken: process.env.OAUTH_REFRESH_TOKEN,
  },
});

transporter.verify((err, success) => {
  err
    ? console.log(err)
    : console.log(`=== Server is ready to take messages: ${success} ===`);
});

let mailOptions = {
  from: "[email protected]",
  to: process.env.EMAIL,
  subject: "Nodemailer API",
  text: "Hi from your nodemailer API",
};

transporter.sendMail(mailOptions, function (err, data) {
  if (err) {
    console.log("Error " + err);
  } else {
    console.log("Email sent successfully");
  }
});

React :

import express from "express";
import nodemailer from "nodemailer";
import cors from "cors";
import dotenv from "dotenv";
import process from "process";

const app = express();

dotenv.config();

app.use(express.json());
app.use(cors());

const port = 3001;
app.listen(port, () => {
  console.log(`Server is running on port: ${port}`);
});

let transporter = nodemailer.createTransport({
  service: "gmail",
  auth: {
    type: "OAuth2",
    user: process.env.EMAIL,
    pass: process.env.WORD,
    clientId: process.env.OAUTH_CLIENTID,
    clientSecret: process.env.OAUTH_CLIENT_SECRET,
    refreshToken: process.env.OAUTH_REFRESH_TOKEN,
  },
});

transporter.verify((err, success) => {
  err
    ? console.log(err)
    : console.log(`=== Server is ready to take messages: ${success} ===`);
});

let mailOptions = {
  from: "[email protected]",
  to: process.env.EMAIL,
  subject: "Nodemailer API",
  text: "Hi from your nodemailer API",
};

transporter.sendMail(mailOptions, function (err, data) {
  if (err) {
    console.log("Error " + err);
  } else {
    console.log("Email sent successfully");
  }
});

As you see the code is the same with the difference that i need to import the modules for react .I also confirm that the dependencies are installed correctly for the react part.

I can use any help or suggestions on this one,

Thank you very much!

cron.schedule() running multiple times:

I have this function which is used to check every second if the current time matches the time of a scheduled email using cron.schedule. However, when it reaches the right time the sendEmail function runs 20+ times as well as the sql query all within a second.

the emails array is structured like this: [[time, address, subject, message, id], [time, address, subject, message, id]…]

code:

function send() {
  for (let i = 0; i < emails.length; i++) {
    let emailTime = emails[i][0];
    let recipient = emails[i][1];
    let subject = emails[i][2];
    let message = emails[i][3];
    let emailId = emails[i][4];

    if (emailTime.split(' ')[1] == '24') { // cron only supports hours 1-23
      let emailTimeSplit = emailTime.split(' ');
      emailTimeSplit.splice(1, 1, '1');
      emailTime = emailTimeSplit.join(' ');
    }

    cron.schedule(emailTime + ' *', () => {

      sendEmail(recipient, subject, message); //asnychronous function in another script

      var sql = `DELETE FROM emails WHERE email_id=${emailId}`; 
      con.query(sql, function (err, result) { //deletes email details from sql table 
        if (err) throw err;
        console.log('items removed!');
      });
    });

  }
}

setInterval(send, 1000);

I tried removing removing the email from the emails array using splice() which somehow made the problem worse and I tried skipping over an email that’s already been sent using continue; statements but that resulted in running even more times.

Any help would be greatly appreciated

How can I get the request URL used by Jquery ajax so I can test it directly in another tab?

I’m working on some ajax functions and it’s inconvenient to have to reload the page and change the conditions every time. I want to directly trigger the command by simply loading the request into a tab. For example:

            $.ajax({
                beforeSend: function(jqXHR, settings) {beforeAjax(settings,1)},
                url: "backend.php",
                type: "POST",
                data: { 
                    mark_done: taskId,
                },
                dataType: "json",
                success: function(msg) {
                    if (ajaxErr(msg)) return;
                    
                },
                error: function(jqXHR, textStatus, errorThrown){ajaxFail(jqXHR, textStatus, errorThrown)},
                done: function(xml) {alert(this.url)}
            });     

What I want is to somehow get the full url request: http//site.com/?name=val&name=val string and print it to the console so I can easily copy and paste the result of the ajax call to test the backend function more efficiently. How can I do that?

Scroll Animation on child div without Scrollbar

I’d like to reproduce an effect similar to this page: https://www.buildinamsterdam.com
When you scroll on this website, the child div (with grids) transform accordingly.

There is no scrollbar in this page, it just when you use the mouse to scroll, the grid columns translate with different speed.

Is there a library that can achieve this or anyone with some ideas on how to approach this. I am learning web animations and this is something i am intrigued to solve.

How to use Filter() on multiple level object

I was wondering how to use filter() on an array of objects like this one:

const tattoos = [
  {
    head: [
      {
        name: "1 - Crâne de pirate (H/F)",
        gender: "HF",
        price: "450",

      },
      {
        name: "2 - Surf LS (H/F)",
        gender: "HF",
        price: "250",
      },
      {
        // etc...
      },
    ],
    torso: [
      {
        name: "1 - Crâne de pirate (H/F)",
        gender: "HF",
        price: "450",

      },
      {
        name: "2 - Surf LS (H/F)",
        gender: "HF",
        price: "250",
      },
      {
        // etc...
      },
    ],

I want to use it in this React Component:

// SIMPLE VERSION FOR EASIER UNDERSTANDING

import React, { useState, useEffect } from "react";

const tattoos = [{...}]

export default function Searchbar() {
  const [filtered, setFiltered] = useState([]);
  const [bodypart, setBodypart] = useState("all");

  function handleChange(e) {
    setBodypart(e.target.value);
  }

  useEffect(() => {
    if (bodypart === "all") {
      setFiltered(tattoos);
      return;
    }

    const filtered = tattoos.filter( // This is where I'm stuck )
    setFiltered(filtered);
  }, []);
  return (
    <div>
        <div>
          <label>
            Bodypart:
          </label>
          <select onChange={handleChange}>
            <option value="all">All</option>
            <option value="head">Head</option>
            <option value="torso">Torso</option>
          </select>
        </div>
    </div>
  );
}

Expected behavior:

  • Click on an option
  • Store the value in “bodypart” state
  • Use filter() on the main array and filter using “bodypart” state

I already tried:

const filtered = tattoos.filter(e => e === bodypart)

const filtered = tattoos.filter(e => e.includes(bodypart))

const filtered = tattoos.filter(e => e.some(bodypart))

const filtered = tattoos.filter(e => Objects.keys(e).includes(bodypart))

But I always ended with an empty array or an error.

Sorry if i’m not very clear but I tried all day to find a solution and now it’s just getting messy in my brain…

Thanks for your help !

smooth transitioning between layers in Leaflet

is there a way to switch baselayers in a smooth manner. For example I have this simple map (taken from here)
with two baselayers. When you change selection then there is something like flickering to move from one baselayer to the other.

Do you know if this can be done in a nice smooth way?

There is a similar post which is 9yrs old but didnt have a solution. I hope you dont mind me posting this one now. Maybe there is something new after 9years.

PS. For some strange reason the snippet doesnt seem to work here. It looks fine on my local system…

<html>
<head>
    <title>A Leaflet map!</title>

    <!-- leaflet v 1.0.3 -->
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"/>
    <script src="https://unpkg.com/[email protected]/dist/leaflet-src.js"></script>

    <style>
        #map {
            height: 100%
        }
    </style>
</head>
<body>

<div id="map"></div>

<script>


    var osm = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 19,
        attribution: '© OpenStreetMap'
    });

    var osmHOT = L.tileLayer('https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', {
        maxZoom: 19,
        attribution: '© OpenStreetMap contributors, Tiles style by Humanitarian OpenStreetMap Team hosted by OpenStreetMap France'
    });

    var map = L.map('map', {
        center: [39.73, -104.99],
        zoom: 10,
        layers: [osm]
    });

    var baseMaps = {
        "OpenStreetMap": osm,
        "OpenStreetMap.HOT": osmHOT
    };

    var layerControl = L.control.layers(baseMaps, {}).addTo(map);


</script>
</body>
</html>

How to generate a sort key from a Collator in Javascript & Node.js?

The Unicode’s ICU standard (International Components for Unicode) says that Unicode collations can be used in two ways: either to compare two strings (compare(s1,s2) method in ICU C++) to know their relative order; or to generate a sort key for any given string (getSortKey()), which is needed when building and sorting an index of multiple strings, like in a database. See the docs:

In Javascript and Node.js, there is Intl.Collator class that implements the compare(s1,s2) method, similar to what’s in ICU. However, this class does NOT provide the other method: for sort key generation. Questions:

  1. Why the getSortKey method is missing in Javascript’s Collator?
  2. Are there any plans to add this method in the future?
  3. Till then, is there any substitute (a package or whatever) that can be used to generate sort keys in JS/Node.js for arbitrary Unicode strings and arbitrary collations?

Searching for “unicode sort keys” and “collations” in NPM & Google don’t yield any sensible results. The only package that has anything to do with sort keys is unicode-collation-algorithm2, which seems to be using sort keys internally in the source code, but doesn’t expose any API for this, and doesn’t accept arbitrary collations.