How to correctly display animated images of significant sizes on a website

I am developing a website where I need to display quite large images (around 1 MB each) as part of a parallax effect. Additionally, I want to use many significantly smaller images as particle effects, utilizing both and . While is a bit more challenging to implement, it offers better performance.

What is the most effective way to implement a significant number of images manipulated by code (e.g., parallax effects or changing positions relative to the mouse cursor)? Are there any libraries specifically suited to handle this issue?

Best practices for managing asynchronous operations in JavaScript to avoid callback hell [closed]

How can I efficiently handle asynchronous operations in JavaScript to avoid callback hell?

I’m currently working on a JavaScript project where I’m dealing with multiple asynchronous operations. However, I’m encountering callback hell, and my code is becoming increasingly difficult to manage. I’m looking for some guidance on how to handle asynchronous operations more efficiently to avoid this issue.

Specifically, I’m interested in learning about best practices or patterns that can help streamline my asynchronous code and prevent it from becoming overly nested with callbacks. Are there any design patterns, libraries, or techniques that are commonly used to address this problem?

I’ve explored using Promises and async/await, but I’m still struggling to refactor my code effectively. Any insights or examples demonstrating how to refactor asynchronous code to make it more manageable would be greatly appreciated.

Additionally, if there are any common pitfalls or mistakes to avoid when dealing with asynchronous operations in JavaScript, I’d love to learn about those as well.

After yarn link, locally started server crashes with the Failed to compile ../../email-editor/lib/cjs/email-editor.js:37:0 Module not found:

I have a repository named email-editor, and I’m trying to locally run my changes with email-editor in the designs project.

I’m using Windows OS and Git Bash as my terminal. When I run each repository separately locally, I don’t encounter any issues. However, when I use yarn link to pull local changes from one repository into the other, I’m unable to start the server. It fails with the following error:

Failed to compile ../../email-editor/lib/cjs/email-editor.js:37:0 Module not found: Can't resolve '../node_modules/style-inject/dist/style-inject.es.js'

What I Tried:
I followed a series of steps to integrate changes from the email-editor repository into the designs project:

Built the email-editor project using yarn build.
Navigated to the designs repository.
Used yarn link email-editor to create a symbolic link to the local email-editor package within designs.
Attempted to start the server in designs by running yarn qa.

Expected Outcome:
I expected the server in the designs project to start successfully after linking email-editor and applying its changes. Specifically, I anticipated that the changes from email-editor would seamlessly integrate into designs, allowing the server to run without issues.

Actual Result:
Unfortunately, the server startup (yarn qa) failed instead of starting successfully as expected. This outcome was unexpected and did not align with the anticipated result of a functional server running with the integrated changes from email-editor.

How to configure Socket.io in nextjs for production?

This is my server.js file

const { createServer } = require('http');
const next = require("next");
const { Server } = require("socket.io");

const dev = process.env.NODE_ENV !== "production";
const hostname = "https://quiet-mooncake-8ff89f.netlify.app/";
const port = 3000;
// when using middleware `hostname` and `port` must be provided below
const app = next({ dev , hostname });
const handler = app.getRequestHandler();

app.prepare().then(() => {
  const httpServer = createServer(handler);

  const io = new Server(httpServer);
  /.../

});

This is my Component

"use client";

import { io } from "socket.io-client";

const socket = io();

I have deployed this project and whenever this Component renders it just shows loading and when i tried looking in the network tab in developers tool it shows a pattern of 2 API hitting again and again.
First is https://quiet-mooncake-8ff89f.netlify.app/socket.io/?EIO=4&transport=polling&t=OyShAVC
which has Parameters as ->

Request URL:
https://quiet-mooncake-8ff89f.netlify.app/socket.io/?EIO=4&transport=polling&t=OyShAVC
Request Method:GET

Status Code:308 Permanent Redirect

Remote Address:[2406:da18:b3d:e202::64]:443

Referrer Policy:strict-origin-when-cross-origin

and Response Parameters as ->

Age:0

Cache-Control:
no-cache

Cache-Status:
“Netlify Edge”; fwd=miss

Content-Type:
text/plain;charset=UTF-8

Date:
Fri, 26 Apr 2024 23:10:28 GMT

Location:
/socket.io?EIO=4&transport=polling&t=OyShAVC

Netlify-Vary:
header=x-nextjs-data,cookie=__prerender_bypass|__next_preview_data

Refresh:
0;url=/socket.io?EIO=4&transport=polling&t=OyShAVC

Server:
Netlify

Strict-Transport-Security:
max-age=31536000; includeSubDomains; preload

X-Content-Type-Options:
nosniff

X-Nf-Request-Id:
01HWEASA1Y24RXM1J3Z4W6W5MQ

And the other one is is just redirecting to 404 page not found
Please tell me what should i do..

I have tried chnaging the hardcoding the URL in my code but it is still nopt working

How to setup a nodejs project so client side node modules resolve in the browser

I have a nodejs and web project that has been getting more complex with time.

In the nodejs side I’m able to easily import and use node modules but on the web page size I’m getting errors when trying to use node modules.

My vscode project is setup like so:

/(nodejs pages here)
/public/(web pages here)
/public/myproject.js
/public/myproject.ts
/public/mypage.html
/public/lib/pixi/(pixijs files here) /* manually copied the files here */
/node_modules/(modules here)

I have a typescript file in the public directory and when I import it into my class the compiler has code complete. But when I load the page in the browser I get errors:

Uncaught TypeError: Failed to resolve module specifier “pixi.js”.
enter image description here

So, I manually moved the pixijs folder from node_modules/pixi.js to a directory in the public folder this seems to work but for some reason it’s not finding one of the classes.

import * as PIXI from 'pixi.js';
import { getCanvasBoundingBox } from "./lib/pixi/pixi.mjs";

Uncaught SyntaxError: The requested module './lib/pixi/pixi.mjs' does not provide an export named 'getCanvasBoundingBox' 

Does anyone know how to setup a nodejs project so that I can import node modules into my client side pages? I put all the web pages in /public because the guides online said that’s what you do but the browser doesn’t seem to like that as I’ve shown.

Here is part of my nodejs server page:

// html page template system
app.set("view-engine", "ejs");

// the default directory path for web pages 
app.use(express.static('public'));

// starts the server
app.listen(PORT, () => {
  var date = new Date();
  var time = date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
  console.clear();
  console.log(`App running at http://localhost:${PORT} at ${time}`);
})

Ideally, what I want is a vscode project that fulfills these requirements:

  • has nodejs pages (ts pages)
  • has web pages (html, ts, css)
  • shares ts classes between nodejs and web ts/js)
  • both can import node modules
  • can use one tsconfig for both (or independent)
  • restarts the server on save
  • doesn’t restart the server on client side ts to js on save
  • i don’t want to use a web pack or whatever because i’m saving a file every 30 seconds (i don’t think i should have to)

All of the requests mention above work independently but it’s been extremely difficult to get them to all work together at the same time.

Problem with cheek radio when adding new dynamic radio input

I have a problem with this code. The radio box has not changed from the first answer when add new answers.

   function addAnswerInputGroup(questionIndex) {
            // Find the wrapper div for answer input groups within the specific question card
            var answerInputGroupWrapper = document.querySelector(`#questionCard${questionIndex} .answer-input-groups`);

            // Generate a unique ID for the new answer input group
            var answerInputId = "answerInput" + (answerInputGroupWrapper.querySelectorAll('.input-group.mb-3').length + 1);

            // Create the new answer input group HTML
            var newAnswerInputGroup = `
                <div class="input-group mb-3" id="${answerInputId}">
                    <span class="input-group-text"><input type="radio" aria-label="Radio for correct answer" name="questions[${questionIndex}][correct_answer]" value="${answerInputGroupWrapper.querySelectorAll('.input-group.mb-3').length}"></span>
                    <span class="input-group-text"><input id="multiplefileupload" type="file" accept=".jpg,.gif,.png" /></span>
                    <input type="text" class="form-control" name="questions[${questionIndex}][answers][]" placeholder="Answer ${answerInputGroupWrapper.querySelectorAll('.input-group.mb-3').length + 1}">
                </div>
            `;

            // Append the new answer input group HTML to the wrapper div
            answerInputGroupWrapper.insertAdjacentHTML('beforeend', newAnswerInputGroup);
        }
<div class="card" id="questionCard1">

    <div class="card-body">


        <h3 class="fs5">A</h3>
        <div class="answer-input-groups">
            <div class="input-group mb-3">
                <span class="input-group-text"><input type="radio" aria-label="Radio for correct answer" name="questions[0][correct_answer]" value="0"></span>
                <span class="input-group-text"><input id="multiplefileupload" type="file" accept=".jpg,.gif,.png"></span>
                <input type="text" class="form-control" name="questions[0][answers][]" placeholder="Answer 1">
            </div>
        </div>

        <button type="button" class="btn btn-primary" onclick="addAnswerInputGroup(1)">Add Answer</button>
    </div>
</div>

<script>
</script>

In order for the problem to appear, add new questions, select the first question, and change the selection for the second question

Application error using heroku will not deploy any of my backend code

I am tyring to deploy the following files after pushig and installing all necessary files but i keep getting the same application error page on Heroku. This is the file one of the files I am pushing

import express from 'express';
import bodyParser from 'body-parser';
import mysql from 'mysql';
import cors from 'cors';
import account from './account.js'
const app = express();

const db = mysql.createConnection({
    host: 'database-3.c12ew6m4ku0j.us-east-2.rds.amazonaws.com',
    user: 'root',
    password: 'password',
    database: 'calendrive'
});

const PORT = 3001;
db.connect(err => {
    if (err) throw err;
    console.log('Connected to the database');
});
app.use(cors());

// Setup CORS settings
app.use(cors({
    // Required for sessions to work
    // Will likely need changed on a production server
    origin: ["http://localhost:8080", "http://localhost:8800"],
    credentials: true
}));
app.use(express.json());


// Get all events
app.get('/events', (req, res) => {
    db.query('SELECT * FROM events', (err, data) => {
        if (err) return res.json(err);
        return res.json(data);
    });
});

// Add new event
app.post('/events', (req, res) => {
    const values = [req.body.name, req.body.desc, req.body.address, req.body.start, req.body.end];
    const q = "INSERT INTO events (`name`, `desc`, `address`, `start`, `end`) VALUES (?)";
    db.query(q, [values], (err, data) => {
        if (err) return res.json(err);
        return res.json(data);
    });
});

// Update event
app.put('/events/:id', (req, res) => {
    const eventId = req.params.id;
    const values = [req.body.name, req.body.desc, req.body.address, req.body.start, req.body.end];
    const q = "UPDATE events SET `name` =?, `desc` =?, `address` =?, `start` =?, `end` =? WHERE id=?"
    db.query(q, [...values, eventId], (err, result) => {
        if (err) return res.json(err);
        return res.json('Event updated');
    });
});

// Delete event
app.delete('/events/:id', (req, res) => {
    const eventId = req.params.id;
    db.query('DELETE FROM events WHERE id=?', [eventId], (err, result) => {
        if (err) throw err;
        res.json('Event deleted');
    });
});

account.setup(app);

// Start the backend HTTP server on port 8800
app.listen((process.env.PORT || PORT), () => {
    console.log(`server running on PORT ${PORT}`);
});

I’ve tried changing things around, commenting out some blocks, but I keep getting the same page. I also tried restarting the dynos and still got nothing.

How to ensure a single instance of the module to be used in different sub apps?

I have a library that makes a few API calls and stores the Promises.
In my application there are different plugins (micro-frontends). I am looking for suggestions around ensuring same memory reference of the library to be returned to different plugins.

My Library code:
FetchUserInfo.js

class FetchUserInfo {
.....
// makes api calls and stores the promise
.....
}

export default (() => {
  let instance = null;
  const fetchUserInfoInstance = (xyz) => {
    if (instance === null) {
      instance = new FetchUserInfo(xyz);
    }
    return instance;
  };
  return fetchUserInfoInstance;
})();

index.js

module.exports = {
  FetchUserInfo,
  FetchUserOrders
};

When I do something like below in Plugin A, a network call happens and promise is stored:

import myLib from '.....';
myLib.FetchUserInfo(abc);

But when I do similar thing in my Plugin B, I see another network call happening as a new instance is created and makes the call. How do I ensure that plugin B get the same memory reference, so I could use the promise created by plugin A??

Prevent module name from being minified in webpack bundle

I have a host application that consumes a remote package through a script tag.

My remote package includes the following ModuleFederationPlugin config within the webpack config

plugins: [
  new webpack.container.ModuleFederationPlugin({
    name: 'myWonderfulModule',
    filename: '[name].js',
    exposes: {
      '.': './src/index.js', 
    },
  }),
],

Typically this results in a file that starts with the following

var myWonderfulModule;
/******/ var __webpack_modules__ = ({

/***/ 986:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {

And I am able to import this module dynamically in the host app using dynamic import

import('myWonderfulModule')...

However, when the remote is minified, it loses the var name at the top of the bundled file (var myWonderfulModule ends up looking like var r or something similar).

I believe this is why I see an myWonderfulModule is not found error when the assets have been minified.

I thought the terser-webpack-plugin might help resolve this issue so I added the following to my remote’s webpack config

optimization: {
  minimize: true,
  minimizer: [
    new TerserPlugin({
      terserOptions: {
        mangle: {
          properties: {
            reserved: ['myWonderfulModule'],
          },
        },
      },
    }),
  ],
},

But still, var myWonderulModule is getting minified to var r.

Perhaps this is because myWonderfulModule isn’t actually part of my code as much as it’s just a name assigned to the module in webpack’s ModuleFederationPlugin config.

So what can I do to preserve that name and still minify the remote bundle…?

JavaScript on change checking all input field values

I have an array of input fields containing carton quantity values, and I want to make sure no more cartons are deducted than needed. It works when there is only one input field, for example when I have:

var input = document.getElementsByName('number_of_cartons');

However I can’t get it work for an array of values.

Here is my code and I would appreciate any feedback. Thanks.

            var input = document.getElementsByName('number_of_cartons[]');
            for (var i = 0; i < input.length; i++) {
                var new_cartons = input[i];
                var existing_cartons = 25;
                var cartons_needed = 10;

                $(new_cartons).on('keyup', function () {
                   if ((new_cartons - existing_cartons) > cartons_needed) 
                       alert("Maximum number of cartons needed is " + cartons_needed + ".");
                });
            }

I can probably change the array of inputs to individual inputs, (i.e. from number_of_cartons[ ] to number_of_cartons_1, number_of_cartons_2, number_of_cartons_3, etc.), however the whole site is using the array version and it would mess up everything, unless I change it all over the site.

Error converting an XML string to an object

This is my code:

    $response = Http::withHeaders([
            "Content-Type" => "application/xml",
            "User-Agent" => "Insomnia/2023.5.6",
            "Accept" => "application/xml"
        ])->withBody($xml, 'application/xml')->post($url);

        if (!$response->successful()) {
            Log::error($response);
            return 0;
        }

        $xmlObject = simplexml_load_string($response->body());
        $body = $xmlObject->children('SOAP-ENV', true)->Body;
        $response = $body->children('ns1', true)->StoreProductsResponse;
        $return = $response->return;
        $namespaces = $xmlObject->getNamespaces(true);

If I do a Log::info($response->body()), the following string appears:

<?xml version="1.0" encoding="UTF-8"?>
 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="https://catalog.nexsysla.com/"><SOAP-ENV:Body><ns1:StoreProductsResponse><return><mark>3nStar</mark><parent>POS</parent><category>Cash Drawers</category><sku>CD250</sku><name>CD250</name><price>48</price><currency>USD</currency><tax_excluded>19</tax_excluded><inventory>4</inventory><short_description>3nStar CD250, Manual &amp; automatic cash drawer, Steel, Black, 330 mm, 343 mm, 90 mm</short_description><long_description>The Cash Drawer CD250 is the ideal choice for businesses needing a compact, heavy duty solution. Available as small as 330mm x 343mm x 90mm, the CD250 is small enough to be used in mobile payment stations such as kiosks or food vendor carts. The cash drawer uses a quick disconnect cable to interface with most major receipt printers, making installation a snap.</long_description>

That is just an example of product information, in xml format. But, the problem is that when I do a Log::info( $xmlObject) after I converted that string to xml with simplexml_load_string, the variable $xmlObject appears empty

And no error appears, or anything. Only the variable appears empty

Unable to filter by request URL in chrome extension

enter image description here

I’m trying to build a chrome extension that will look for the response of a url that contains “bounds” . The full URL is:

https://www.land.com/api/0/United-States/all-land/zoom-12/bounds-38.487397840020606-n98.67873224975584-38.67660627098903-n98.39205775024412/?sk=_cljFjdpxQz^utWzgJnbFwy@|`U_mIwnC

I’m starting with a sanity check to make sure that I am selecting the right URL:

function handleRequestFinished(request) {
  if (
    request.request.url.includes("bounds") &&
    request.request.url.includes("land")
  ) {
    console.log("---------------------------------");
    console.log(request.request.url);
    console.log("request");
    console.log("---------------------------------");
  }
}

chrome.devtools.network.onRequestFinished.addListener(handleRequestFinished);

However I am getting all kinds of urls printed to the console which do not appear to have either of the conditions met. What am I doing wrong?

Able to access dom element in javascript without explicitly defining a query selector for it

In my code I am making a simple library application and in my javaScript code for some reason, without checking, I had assumed I had defined a query selector by the variable name of read for the checkbox input in the add book button pop-up menu, however I hadn’t, I then referenced this in my **submit and cancel eventlisteners **and there was no error. i am confused as to why this is happening as I believed that elements could not be accesses unless you selected them using one of the defined document methods e.g. querySelector()

HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Javascript Library</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- popup form -->
  <div class="popup-form">
    <button class="cancel">x</button>
    <form class="form">
      <ul>
        <li>
          <label for="title">Title*</label>
          <input type="text" id="title" required>
        </li>
        <li>
          <label for="author">Author*</label>
          <input type="text" id='author' required>
        </li>
        <li>
          <label for="pages">Pages*</label>
          <input type="number" id="pages" min="0" required>
        </li>
        <li>
          <label for="read">Read</label>
          <input type="checkbox" id = 'read'>
        </li>
        <button type='button' class="submit">Submit</button>
      </ul>
    </form>
  </div>

  <!-- header -->
  <header>
    <h1 class="title">Fkhadim's Library</h1>
  </header>
  <!-- add book button -->
  <button class="add-book">Add Book</button>

  <!-- main article -->
  <div class="book-grid">
    
  </div>
  <script src="script.js"></script>
</body>
</html>

CSS

@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');

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

li {
  list-style-type: none;
}

body {
  background-color: rgb(240, 232, 232);
  font-family: 'Poppins', sans-serif;
}

/* header */

header {
  background-color: #fff;
  height: 15vh;
  display: flex;
  align-items: center;
  justify-content: center;
  color: black;
  font-family: 'Poppins', sans-serif;
  font-size: 25px;
}

h1 {
  text-align: center;
}

/* add book button */

.add-book:active {
  background-color: black;
  color: #fff;
  transition-duration: 300ms;
}

.add-book {
  display: block;
  margin: 0 auto;
  padding: 10px 35px;
  font-size: 22px;
  margin-top: 20px;
  background-color: #fff;
  border: none;
  border: 2px solid black;
  border-radius: 5px;
}

/* book grid and card styling */

.book-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(450px, 1fr));
  gap: 20px;
  margin: 0 auto;
  margin-top: 20px;
  max-width: 70vw;
  align-items: stretch;
}

.card {
  background-color: #fff;
  padding: 30px;
  padding-top: 20px;
  display: grid;
  grid-template-columns: 6fr 4fr;
  gap: 10px;
  border: 2px solid black;
}

.card-title {
  font-size: 30px;
  font-weight: 700;
}

.card-author {
  font-size: 16px;
  font-weight: 500;
}

.card-pages {
  font-size: 20px;
}

.card-read {
  font-size: 18px;
}

.card-buttons {
  display: flex;
  gap: 10px;
  align-items: flex-end;
}

.card-buttons button {
  flex: 1;
  height: 25%;
  max-height: 50px;
  background-color: #fff;
  border: none;
  border: 1px solid black;
  border-radius: 3px;
  padding: 0 10px;

}

.card-buttons button:hover {
  background-color: black;
  color: #fff;
  transition-duration: 200ms;
}

/* popup form */
.popup-form {
  position: fixed;
  background-color: rgb(240, 232, 232);
  display: none; /*switches to display flex in javascript */
  flex-direction: column;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border: 2px solid black; 
  border-radius: 10px;
}

.cancel {
  align-self: flex-end;
  font-size: 20px;
  padding: 3.5px 10px;
  margin-top: 10px;
  margin-right: 10px;
  background-color: red;
  border: none;
  border-radius: 15px;
  border: 1px solid black;
}

.cancel:active {
  background-color: rgb(175, 13, 13);
}

.popup-form form ul li label {
  font-size: 25px;
}

.popup-form form ul li {
  margin-bottom: 10px;
}

.popup-form form ul li label {
  display: block;
  margin-bottom: 5px;
}

.popup-form form ul li input {
  padding: 5px;
  border-radius: 3px;
  height: 30px;
  border: 1px solid #ccc;
  font-size: 20px;
}

.popup-form form ul li:nth-child(4) {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 20px;
}

#read {
  margin-left: 20px;
}

form {
  padding: 0 30px;
  padding-bottom: 25px;
}

.submit {
  padding: 5px 20px;
  font-size: 22px;
  background-color: #fff;
  border: none;
  border: 2px solid black;
  border-radius: 5px;
}

.submit:active {
  background-color: black;
  color: #fff;
  transition-duration: 200ms;
}

/* media queries */
@media (max-width: 640px){
  .book-grid{
    grid-template-columns: 1fr;
  }
  .card-buttons {
    flex-direction: column;
    align-items: stretch;
    justify-content: center;
    height: 100%;

  }
  .card {
    padding: 20px;
  }
}

JAVASCRIPT

const addBook = document.querySelector('.add-book');
const popupForm = document.querySelector('.popup-form');
const form = document.querySelector('.form');
const cancel = document.querySelector('.cancel');
const submit = document.querySelector('.submit');
const title = document.querySelector('#title');
const pages = document.querySelector('#pages');
const author = document.querySelector('#author');
const bookgrid = document.querySelector('.book-grid');

function Book(title, author, pages, read){
  this.title = title;
  this.author = author;
  this.pages = pages;
  this.read = read;
}

Book.prototype.addCard = function(){
  let card = document.createElement('div');
  let cardDesc = document.createElement('div');
  let cardButtons = document.createElement('div');
  let cardTitle = document.createElement('div');
  let cardAuthor = document.createElement('div');
  let cardPages = document.createElement('div');
  let cardRead = document.createElement('div');
  let read = document.createElement('button');
  let del = document.createElement('button');
  card.classList.add('card');
  cardDesc.classList.add('card-desc');
  cardButtons.classList.add('card-buttons');
  cardTitle.classList.add('card-title');
  cardAuthor.classList.add('card-author');
  cardPages.classList.add('card-pages');
  cardRead.classList.add('card-read');
  read.classList.add('read');
  del.classList.add('delete');

  read.addEventListener('click', () => {
    if(this.read){
      cardRead.textContent = 'not read'
      this.read = false;
    }
    else {
      cardRead.textContent = 'read'
      this.read = true;
    }
  })
  del.addEventListener('click', () => {
    card.remove();
  })

  cardTitle.textContent = this.title;
  cardAuthor.textContent = this.author;
  cardPages.textContent = this.pages;
  cardRead.textContent = this.read ? 'read': 'Not Read'

  read.textContent = 'Read';
  del.textContent = 'Delete';

  cardDesc.appendChild(cardTitle);
  cardDesc.appendChild(cardAuthor);
  cardDesc.appendChild(cardPages);
  cardDesc.appendChild(cardRead);

  cardButtons.appendChild(read);
  cardButtons.appendChild(del);

  card.appendChild(cardDesc);
  card.appendChild(cardButtons);

  bookgrid.appendChild(card);
}


addBook.addEventListener('click', () => {
  popupForm.style.display = 'flex';
})

cancel.addEventListener('click', () => {
  popupForm.style.display = 'none';
    title.value = '';
    pages.value = '';
    author.value = '';
    read.checked = false
    
}) 

submit.addEventListener('click', () => {
  if(form.checkValidity()){
    popupForm.style.display = 'none';
    const newBook = new Book(title.value, author.value, pages.value, read.checked)
    title.value = '';
    pages.value = '';
    author.value = '';
    read.checked = false;
    newBook.addCard()
  }
})

// example book
const theHobbit = new Book('The Hobbit', 'George R.R Martin', 576, true);
theHobbit.addCard();

I tried to play around with different ways to log the read variable but I had no luck finding out how this happened I asked chatgpt and it couldnt give me a straight answer so I just want to understand what this is. I feel like it may have to do with me being new to this object oriented style of programming.

Hoppscotch Pre-request Script async request

I’m experiencing an issue with the asynchronous execution order of .then() in a fetch request within my JavaScript script. The script is supposed to fetch an authentication token and then set it in an environment variable. However, it seems like the URL call for my application is happening before the .then() chains execute, leading to the use of an unset token. I need the token to be retrieved and set before making a subsequent request. So it successfully retrieves the token and the script is being executed until the first part of fetch, but before the .then it calls the url and then executes the rest of the script.

const authUrl = "https://auth0.com/oauth/token";
const authBody = JSON.stringify({
  grant_type: "password",
  client_id: "client_id",
  client_secret: "client_secret",
  scope: "openid profile email",
  audience: "https://audience/",
  username: "username",
  password: "password"
});
console.log("nach dem ziehen des token")
// Execute the fetch request to authenticate
fetch(authUrl, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: authBody
})
.then(response => response.json())
.then(data => {
  if (data.access_token) {
    // Set the access token in an environment variable
    pw.env.set("accessToken", data.access_token);
        pw.env.set("accessToken", data.access_token);
    console.log("accessToken set:", data.access_token); // to check the log
  } else {
    console.error('Error retrieving the token:', data);
  }
})
.catch(error => console.error('Error in fetching auth token:', error));

How do I delete old deployments (versions) in Google Apps Script when I have over 1700 versions that are active or archived?

I have 1748 versions in Google Apps Script including the current version. I am trying to get down to below 200 to get below the 200 maximum coming in June. When I go to Manage Deployments, I see a bunch of versions in Active (versions I don’t use anymore) and a bunch of versions in Archived (2 of which I use). I also use the current version.

What am I doing wrong and how to delete more? I’m also considering starting the project over by copying/pasting the current version, but it would be nice to also keep the other 2 versions that I use easily available.

I tried deleting some versions but only 4 of the 1700+ were able to be deleted. I was expecting to be able to delete more versions