Nativescript Error when I want to run on Android emulator

the app is a bit old but I just want to run it. NativeScript error when I want to run on Android device. running code : ns run android -> Error: Unexpected token '.'

Node: 12.19.0
npm: 6.14.8

"dependencies": {
    "@nativescript-community/ble": "^3.0.8",
    "@nativescript/core": "^7.3.0",
    "@nativescript/theme": "^3.0.0",
    "@nstudio/nativescript-checkbox": "^2.0.3",
    "@vue/devtools": "^6.0.0",
    "clean-webpack-plugin": "^4.0.0",
    "jwt-decode": "^3.0.0",
    "nativescript-appavailability": "^1.3.2",
    "nativescript-audio": "~6.1",
    "nativescript-socketio": "^3.3.1",
    "nativescript-toasty": "^3.0.0-alpha.2",
    "nativescript-vue": "^2.8.1",
    "nativescript-vue-devtools": "^1.4.0",
    "vue-i18n": "^8.22.0",
    "vuex": "^3.1.1",
    "vuex-simple": "^2.2.0"
  }
  "devDependencies": {
    "@babel/core": "^7.11.6",
    "@babel/preset-env": "^7.11.5",
    "@intlify/vue-i18n-loader": "^1.0.0",
    "@nativescript/android": "7.0.0",
    "@nativescript/types": "^7.0.4",
    "@nativescript/webpack": "^3.0.7",
    "@types/node": "^14.11.8",
    "babel-loader": "^8.1.0",
    "nativescript-vue-template-compiler": "^2.8.1",
    "nativescript-worker-loader": "~0.12.1",
    "node-sass": "^9.0.0",
    "sass": "^1.27.0",
    "typescript": "^4.0.3",
    "vue": "^2.6.12",
    "vue-class-component": "^7.2.3",
    "vue-loader": "^15.9.3",
    "vue-property-decorator": "^9.0.2"
  }

Please help me

background video auto play not working on chrome for the first time

i use elementor section background video. i unmute this the video useing this code

document.addEventListener('DOMContentLoaded', function() {
    var heroBackgroundVideo = document.querySelector('#myVideo div video.elementor-html5-video');
    
    // Set the video to not be muted (sound on)
    heroBackgroundVideo.muted = false;
    
    // Set the volume to 1 (maximum volume)
    heroBackgroundVideo.volume = 1;
});

it works fine. but the problem is when someone visite the site first time the auto play not working. but when reload means secound time visit the site it working fine.

i mean only auto play not working for the first time .
the video is not mute.
I need the solution in javascript code.
thanks

Hooks in server/client side in Next.js 13

When we build a page with SSR, can it have a component that uses a state ? Or is state full-stop client only, if so do we need to at least make that component run on the client every time we want to add interactivity that needs to remember user’s actions?

This feel’s like something I already should comprehend but with the drought that is reliable information on Next 13 I’m a bit confused.

As always thanks for help!

React Custom Hook Undefined

Very new to React and been trying to figure out custom hooks and keep getting stumped. Here’s my latest, hoping someone can help me make sense of what I’m seeing.

I’m taking a very iterative approach to building up to a functional custom hook. Right now I have the following:

The custom hook:

const useHandleDeleteClick = () => {
    
    console.log('custom hook');
    return;

};

export default useHandleDeleteClick;

Component Code:

import { useParams} from "react-router-dom";
import useHandleDeleteClick from "./useCustomHookFile";

const ItemDetails = () => {
    const { customerId, id } = useParams();
    const handleDeleteClick = useHandleDeleteClick();
    console.log(handleDeleteClick);
        
    return (        
        <a href='#' onClick={() => handleDeleteClick()}>
            Do stuff
        </a>
    );
    
}
 
export default ItemDetails;

Two questions:

  1. I see that the onClick of the “Do stuff” link is invoked when the page loads/is rendered. Is there a way to prevent that?
  2. handleDeleteClick is undefined and I’m really not sure why so the onClick effectively does nothing.

If I can get this wired up correctly I can start to build in the actual desired functionality.

Any help would be much appreciated. Thank you in advance!

Only Listen for change to checkbox when it is checked by the user and not by my code?

I have a list of posts and each post has a checkbox at the top and at the bottom. And I am trying to ensure that the checkboxes stay in sync with eachother:

This code works in one direction: so if you click the top checkbox, it will tick the bottom checkbox for you:

document.querySelectorAll('.mypost').forEach((i) => {
    var my_buttonTop = i.querySelector('.button-check-top .button-check');
    var my_buttonBottom = i.querySelector('.button-check-bottom .button-check');

    my_buttonTop.addEventListener('change', (event) => {
        my_buttonBottom.click();
    })
});

However, I want it to work both ways so I added an EvenListener for the other checkbox as well:

document.querySelectorAll('.mypost').forEach((i) => {
    var my_buttonTop = i.querySelector('.button-check-top .button-check');
    var my_buttonBottom = i.querySelector('.button-check-bottom .button-check');

    my_buttonTop.addEventListener('change', (event) => {
        my_buttonBottom.click();
    })
    my_buttonBottom.addEventListener('change', (event) => {
        my_buttonTop.click();
    })
    
});

Now the two conflicts with eachother, because the code “clicks” the checkbox and then it triggers the EventListener all over again.
So I need some way to trigger the eventlistener only when the user clicks the checkbox and not when the status of the checkbox is changed by my code.

I have searched all over for potential solutions online, but I only find potential jquery solutions and I want to do this in javascript.

Html theme switcher

I want to to implement a theme switcher. I followed this tutorial but it’s not working. When I click on the button, nothing changes. You can find the js at the bottom (theme switcher);the html is in the “menu”;the css is at the bottom.

I think the problem is inside the js but can’t understand what it is

/*<!-------Script du menu------->*/

const list = document.querySelectorAll('.list');
function activeLink(){
  list.forEach((item) =>
  item.classList.remove('active'));
  this.classList.add('active');
}
list.forEach((item) =>  
item.addEventListener('click', activeLink));

window.onmousedown = e => {
    const track = document.getElementById("image-track");

    track.dataset.mouseDownAt = e.clientX;
}

window.onmouseup = () => {
    const track = document.getElementById("image-track");

    track.dataset.mouseDownAt = "0";
    track.dataset.prevPercentage = track.dataset.percentage;
}

window.onmousemove = e => {
    const track = document.getElementById("image-track");
    const tips = document.getElementById("tips");
    if(track.dataset.mouseDownAt == "0") return;
    
    const mouseDelta = parseFloat(track.dataset.mouseDownAt) - e.clientX, maxDelta = window.innerWidth / 2;

    const percentage = (mouseDelta / maxDelta) * -100, nextPercentage = Math.max(Math.min(parseFloat(track.dataset.prevPercentage) + percentage, 0), -100);
    
    track.dataset.percentage = nextPercentage;
    
    track.animate({
        transform: `translate(${nextPercentage}%, -50%)`
    }, { duration: 1200, fill: "forwards" });

    tips.animate({
        transform: `translate(${nextPercentage * 2}%, -50%)`
    }, { duration: 1200, fill: "forwards" });

    for(const image of track.getElementsByClassName("image")) {
        image.animate({
            objectPosition: `${100 + nextPercentage}% center`
        }, { duration: 1200, fill: "forwards" });
    }
}


/*fonction pour v�rifier l'age*/
function verifAge() {
    var age = document.getElementById('age').value;
if (age>130) {
    alert("Personne n'a vecu aussi longtemps ! Age entre : "+ age+"ans");
} else if (age<18) {
    alert("Vous devez etre majeur pour realiser ce questionnaire ! Age entr� : "+ age+"ans");
} else {
    alert("Vous avez l'age requis !");
}

/*fonction pour v�rifier l'age*/
function verifnumber() {
    var age = document.getElementById('rep1').value;
if (age>10) {
    alert("Vous ne pouvez pas alle au dela de 10");
} else if (age<0) {
    alert("Vous ne pouvez pas alle en dessous de 0");
}
}
}

/*fonction pour afficher un message*/
function messInfo(ntext) {
var x = document.getElementById('info');
x.innerHTML = ntext;
x.className = "show";
setTimeout(function(){ x.className = x.className.replace("show", ""); }, 3000);
}

/*verification question 4*/
if (document.getElementById("quest4").checked === true) {
var preference = "Led Zeppelin";
}

/*verification question 5*/
if (document.getElementById("quest5").checked === true) {
var preference = "Au grunge";
}

/*theme switcher*/
const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
const currentTheme = localStorage.getItem('theme');

if (currentTheme) {
    document.documentElement.setAttribute('data-theme', currentTheme);
  
    if (currentTheme === 'dark') {
        toggleSwitch.checked = true;
    }
}

function switchTheme(e) {
    if (e.target.checked) {
        document.documentElement.setAttribute('data-theme', 'dark');
        localStorage.setItem('theme', 'dark');
    }
    else {        document.documentElement.setAttribute('data-theme', 'light');
          localStorage.setItem('theme', 'light');
    }    
}

toggleSwitch.addEventListener('change', switchTheme, false);
@import url('https://fonts.googleapis.com/css?family=Mooli&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@500&display=swap');
/* -------Variables------- */

:root {
    --navButtonSize: 25%;
    --text: #020401;
    --background: #f1f8ef;
    --primary: #94d283;
    --secondary: #d5edce;
    --accent: #58b040;
}

[data-theme="theme-dark"] {
    --navButtonSize: 25%;
    --text: #f1f8ef;
    --background: #020401;
    --primary: #94d283;
    --secondary: #0d1a09;
    --accent: #b6e0aa;
}

/* -------Cacher la barre de scroll------- */

body 
{
  -ms-overflow-style: none; /* Pour Internet Explorer, Edge */
  scrollbar-width: none; /* Pour Firefox */
  overflow-y: scroll; 
}

body::-webkit-scrollbar 
{
  display: none; /* Pour Chrome, Safari, and Opera */
}

/* -------Fond/Police------- */

body 
{
    font-family: 'Mooli', sans-serif;
    background: var(--background);
}

/* ----------------------------Menu---------------------------- */

/* -------Barre du menu------- */

nav
{
    position: fixed;
    margin: 0px auto 0;
    margin-left: 0px;
    top: 5px;
    width: 98.5%;
    height: 50px;
    background: var(--secondary);
    border-radius: 8px;
    font-size: 0;
    box-shadow: 0 2px 3px 0 rgba(0,0,0,.1);
}

/* -------Le texte des boutons du menu------- */

nav a
{
    font-size: 30px;
    text-transform: uppercase;
    color: var(--text);
    font-family: 'Oswald', sans-serif;
    text-decoration: none;
    line-height: 50px;
    width: 80px;
    position: relative;
    z-index: 1;
    display: inline-block;
    text-align: center;
}

/* -------Barre de survole de bouton------- */

nav .animation
{
    position: absolute;
    height: 10%;
    bottom: 0;
    z-index: 0;
    background: var(--primary);
    border-radius: 8px;
    transition: all .5s ease 0s;
    opacity: 0;
}

/* -------Indicateur de la page------- */

.indicator
{
    position: absolute;
    height: 100%;
    top: 0;
    z-index: 0;
    background: var(--primary);
    border-radius: 8px;
    transition: all .5s ease 0s;
}

/* -------Cache le surplus (le texte qui monte) derrière le menu------- */

.cache
{
    position: fixed;
    top: 0px;
    left: 0;
    width: 100%;
    height: 55px;
    background: var(--background);
    z-index: 0;
}

/* -------Les enfants de la barre de survole, de l'indicateur et des boutons du menu------- */

nav a:nth-child(1)
{
    width: var(--navButtonSize);
}
nav a:nth-child(1):hover~.animation
{
    width: var(--navButtonSize);
    left: 0%;
    opacity: 1;
}
nav a:nth-child(1).active~.indicator
{
    width: var(--navButtonSize);
    left: 0%;
}
nav a:nth-child(1).active:hover~.animation
{
    opacity: 0;
}

nav a:nth-child(2)
{
    width: var(--navButtonSize);
}
nav a:nth-child(2):hover~.animation
{
    width: var(--navButtonSize);
    left: 25%;
    opacity: 1;
}
nav a:nth-child(2).active~.indicator
{
    width: var(--navButtonSize);
    left: 25%;
}
nav a:nth-child(2).active:hover~.animation
{
    opacity: 0;
}

nav a:nth-child(3)
{
    width: var(--navButtonSize);
}
nav a:nth-child(3):hover~.animation
{
    width: var(--navButtonSize);
    left: 50%;
    opacity: 1;
}
nav a:nth-child(3).active~.indicator
{
    width: var(--navButtonSize);
    left: 50%;
}
nav a:nth-child(3).active:hover~.animation
{
    opacity: 0;
}

nav a:nth-child(4)
{
    width: var(--navButtonSize);
}
nav a:nth-child(4):hover~.animation
{
    width: var(--navButtonSize);
    left: 75%;
    opacity: 1;
}
nav a:nth-child(4).active~.indicator
{
    width: var(--navButtonSize);
    left: 75%;
}
nav a:nth-child(4).active:hover~.animation
{
    opacity: 0;
}

nav a:nth-child(5)
{
    width: var(--navButtonSize);
}
nav a:nth-child(5):hover~.animation
{
    width: var(--navButtonSize);
    left: 100%;
    opacity: 1;
}
nav a:nth-child(5).active~.indicator
{
    width: var(--navButtonSize);
    left: 100%;
}
nav a:nth-child(5).active:hover~.animation
{
    opacity: 0;
}

/* ----------------------------Page---------------------------- */

/* -------Feuille de style pour la page------- */

.page {
    position: relative;
    z-index: -1;
}

ion-icon {
    color: var(--text);
    font-size: 30px;
}

.logo-text {
    color: var(--text);
    padding-left: 450px;
    height: 450px;
    width: 1000px;
}

.quizz {
    float: left;
    padding-top: 50px;
    padding-left: 0px;
    height: 350px;
    width: 800px;
}

.menu-text {    
    padding-top: 30px;
    color: var(--text);
    font-size: 50px;
    padding-left: 900px;
    text-align: justify;
}

.tuto { 
    padding-top: 50px;
    color: var(--text);
    font-size: 50px;
    padding-left: 50px;
}







/*slider switch css */
.theme-switch-wrapper {
    display: flex;
    align-items: center;
    
    em {
      margin-left: 10px;
      font-size: 1rem;
    }
  }
  .theme-switch {
    display: inline-block;
    height: 34px;
    position: relative;
    width: 60px;
  }
  
  .theme-switch input {
    display:none;
  }
  
  .slider {
    background-color: #ccc;
    bottom: 0;
    cursor: pointer;
    left: 0;
    position: absolute;
    right: 0;
    top: 0;
    transition: .4s;
  }
  
  .slider:before {
    background-color: #fff;
    bottom: 4px;
    content: "";
    height: 26px;
    left: 4px;
    position: absolute;
    transition: .4s;
    width: 26px;
  }
  
  input:checked + .slider {
    background-color: #66bb6a;
  }
  
  input:checked + .slider:before {
    transform: translateX(26px);
  }
  
  .slider.round {
    border-radius: 34px;
  }
  
  .slider.round:before {
    border-radius: 50%;
  }
  
<!DOCTYPE html>
<html>

<!-------Paramètres------->

  <head>
    <meta charset="utf-8">
    <title>E-sciences</title>
    <link rel="stylesheet" href="css/menu-style.css">
    <script src="js/script.js"></script>
    <link rel="icon" type="images/png" href="image/logo.jpg">
    <link href="https://fonts.cdnfonts.com/css/huglove" rel="stylesheet">
  </head>
  
<style>
@import url('https://fonts.cdnfonts.com/css/huglove');
</style>


<!-------menu------->

  <body>
    <div class="cache"></div>
    <nav>
      <a class='list active' href="menu.html"><ion-icon name="home"></ion-icon> • Accueil</a>
      <a class='list' href="quizz1.html"><ion-icon name="game-controller"></ion-icon> • Quizz</a>
      <a class='list' href="quizz2.html"><ion-icon name="newspaper"></ion-icon> • Carnet de bord</a>
      <a class='list' href="#"><ion-icon name="people"></ion-icon> • Avis</a>
      <div class="animation start-home"></div>
      <div class="indicator"></div>
      <div class="theme-switch-wrapper">
          <label class="theme-switch" for="checkbox">
      <input type="checkbox" id="checkbox" />
      <div class="slider round"></div></label>
    </div> 
    </nav>
    

<script type="module" src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.esm.js"></script>
<script nomodule src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.js"></script>

<!-------Page------->
    <div class="page">
        <img class="logo-text" src="image/logo_text.png" draggable="false">
        <img class="quizz" src="image/quizz.jpg" draggable="false">
        <p class="menu-text">• Avec Rythmique essayez nos quizz musicaux,<br>‎ ‎ ‎ testez vos connaissances et amusez vous !</p>
        <p class="menu-text">• Rythmique c'est gratuit et vos donnees <br>‎ ‎ ‎ ‎ ‎ ‎ ‎ sont completement securisees !</p>
        <p class="tuto">Tutoriel :<br><br>Dans la barre de navigation, cliquez sur le Quizz 1 ou 2. Ensuite, dans le Quizz, repondez aux questions et cliquez sur valider pour voir les reponses et passe a la suite.</p>

    </div>
    
  </body>
</html>

Im integrating with my auctions website but the api dint working properly

im building a auctions website in MERN Stack and tried using CLOUDINARY for storage, but my upload api for cloudinary is not working and it giving me a bad request error so im sharing the code, every help will be appreciated

this is the upload Controller of the website in nodejs here im uploading image and retriving the public id of cloudinary

const cloudinary = require("cloudinary").v2;
require("dotenv").config();

cloudinary.config({
  cloud_name: process.env.CLOUD_NAME,
  api_key: process.env.KEY,
  api_secret: process.env.SECRET,
});

exports.uploadImage = (req, res, next) => {
  try {
    if (!req.file) {
      return res.status(400).json({ error: "No file uploaded" });
    }

    const uploadOptions = { resource_type: "auto" };

    cloudinary.uploader
      .upload_stream(uploadOptions, (error, result) => {
        if (error) {
          console.error("Error uploading image to Cloudinary:", error);
          return res.status(500).json({ error: "Error uploading image" });
        }

        if (!result || !result.secure_url) {
          console.error("Invalid response from Cloudinary:", result);
          return res
            .status(500)
            .json({ error: "Invalid response from Cloudinary" });
        }

        const uploadedImage = {
          public_id: result.public_id,
          secure_url: result.secure_url,
          format: result.format,
          width: result.width,
          height: result.height,
        };

        // Check if the format is supported (e.g., you can add more supported formats as needed)
        const supportedFormats = ["jpg", "jpeg", "png", "gif"];
        if (!supportedFormats.includes(result.format.toLowerCase())) {
          console.error("Unsupported image format:", result.format);
          return res.status(400).json({ error: "Unsupported image format" });
        }

        res.json({ message: "Image uploaded to Cloudinary", uploadedImage });
      })
      .end(req.file.buffer);
  } catch (error) {
    console.error("Error during image upload:", error);
    res.status(500).json({ error: "Internal server error" });
  }
};

// exports.upload = upload.single("image");

exports.getDownloadURLFromCloud = async (req, res) => {
  const imageId = req.params.public_id;

  try {
    const result = await cloudinary.api.resource(imageId);

    if (!result.secure_url) {
      return res.status(404).json({ error: "Image not found" });
    }

    const downloadURL = result.secure_url;
    res.json({ downloadURL });
  } catch (error) {
    console.error("Error fetching image from Cloudinary:", error);
    res.status(500).json({ error: "Error fetching image from Cloudinary" });
  }
};

this is the route of upload

const express = require("express");
const fs = require("fs");
const util = require("util");
const unlinkFile = util.promisify(fs.unlink);
const router = express.Router();
const multer = require("multer");
const isAuth = require("../middlewares/isAuth");
const {
  uploadImage,
  getDownloadURLFromCloud,
} = require("../controllers/upload");

const upload = multer({ dest: "uploads" });

// @route   GET /upload/image/:key
// @desc    Get image with key
// @access  protected
router.get("/image/:imageId", async (req, res) => {
  try {
    const fileBuffer = await getDownloadURLFromCloud(req.params.key);

    res.status(200).send(fileBuffer);
  } catch (error) {
    console.log(error);
    res.status(500).json({ errors: { msg: "Server Error" } });
  }
});

router.post("/image", isAuth, upload.single("image"), async (req, res) => {
  const file = req.file;

  try {
    const result = await uploadImage(file);
    await unlinkFile(file.path);
    res.status(200).json({ imagePath: `/upload/image/${result.public_id}` });
  } catch (error) {
    console.log(error);
    res.status(500).json({ errors: { msg: "Server Error" } });
  }
});

module.exports = router;

check status of checkbox when it is clicked

I have a checkbox in each one of my posts, and I want to detect the status of a checkbox every time a change is made to one of the checkboxes. Somewhere I’m doing something wrong.

This doesn’t work:

document.querySelectorAll('.mypost').forEach((i) => {
    var myButton = i.querySelector('.my-check-box');
    myButton.addEventListener('change', (event) => {
            if (myButton.checked == true; ) {
                alert('checkbox status is checked');
             } else {
                 alert('checkbox status is unchecked');
            }
    }
});

But when I use it without the condition then it works:

document.querySelectorAll('.mypost').forEach((i) => {
    var myButton = i.querySelector('.my-check-box');
    myButton.addEventListener('change', (event) => {
        alert('hello');
    }
});

So my eventlistener is working but not the way I am targeting the checkbox inside of my condition statement.

So my problem is here:

if (myButton.checked == true; ) {

What am I doing wrong?

Recharts, is it possible to change the tooltip type?

I’m using Recharts to create an area chart with duplicate x-axis values. I want the tooltip interaction for the points on the chart to mimic that of a scatter chart, where it correctly displays data. Currently, the tooltip doesn’t render the correct data for some points. Is there a way to achieve this behavior in Recharts, similar to how it works in a scatter chart?

Here is an example of my area chart, and the scatter chart.
https://codesandbox.io/s/unruffled-booth-22vqrv?file=/src/App.js

Any help would be great.

Accessing Nested Objects in JavaScript where inner objects have serial numbers as labels

I have a nested object where the inner objects have random serial numbers as their labels.

If I have data like this:

const user = {
    id: 101,
    email: '[email protected]',
    personalInfo: {
        name: 'Jack',
        address: {
            line1: 'westwish st',
            line2: 'washmasher',
            city: 'wallas',
            state: 'WX'
        }
    }
}

I can access the inner object with

const name = user.personalInfo.name;
const userCity = user.personalInfo.address.city;

But my inner objects have random serial numbers, not static labels like address as in the above example.

{
    "id": "48121be5c6b55ae23928316f5",
    "component": "select",
    "customFields": [

    ],
    "index": 0,
    "label": "Select",
    "description": null,
    "placeholder": null,
    "editable": true,
    "options": {
      "f1c7363b085cd671a59": {
        "index": 0,
        "value": "AA",
        "label": "A"
      },
      "3d8508fb86c6af84637": {
        "index": 1,
        "value": "BB",
        "label": "B"
      },
      "615b8ba2c0b7e88b8b5": {
        "index": 2,
        "value": "DD",
        "label": "D"
      }
    },
    "required": false,
    "validation": "/.*/",
    "imported": false
  }

How do I access the value for each inner object of the options object?

How to get the inner text of an anchor tag from a gridjs table

Consider an anchor tag for instance: <a href="/stats/ABCXYZ/1">ABCXYZ</a> I want to be able to extract the text ABCXYZ and pass it to myFunction as an argument. This anchor tag is one of the elements of the following gridjs table:

<script>
  new gridjs.Grid({
    columns: [
      { id: 'serial', name: 'Serial' },
      { id: 'version', name: 'Version' },
      { id: 'is_active', name: 'Active=1, Stopped=0' },
      { 
              id: 'action', 
              name: 'Stop',
              formatter: (cell, row) => {
                return gridjs.h('button', {
                  className: 'py-2 mb-4 px-4 border rounded-md text-white bg-blue-600',
                        onClick: () => myFunction(`"${row.cells[0].data}"`)
                }, 'Stop');
              }    
      },
    ],
    data: [
      {% for test in tests %}
        { serial: gridjs.html("<a href={{ url_for('stats.dash_stats', serial=test['device_serial'], test_id=test['id']) }}>{{ test['device_serial'] }}</a>"),
          version: "{{ test['version'] }}",
          is_active: "{{ test['is_active'] }}",
        },
      {% endfor %}
    ],
    search: {
      selector: (cell, rowIndex, cellIndex) => [0, 1, 2].includes(cellIndex) ? cell : null,
    },
    sort: true,
    pagination: true,
  }).render(document.getElementById('table'));
</script>

However, in myFunction the a tag object is not accessible. For instance, when I tried to query the href attribute or innerText, I get undefined logged in console:

      <script>
       function myFunction(serial) {
         let text = "Press a button!nEither OK or Cancel.";


        console.log(serial.href) # undefined
        console.log(serial.innerText) # undefined
      }
      </script>

My goal is that myFunction is called with innerText of the anchor tag which ABCXYZ in this example.

Modal shows up after second button click

I have an issue. After clicking on button with content “CHECK TASKS” nothing happens. But when I click second time the button, the modal shows up. I want to make it showed up after first click.

HTML CODE:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,700;1,400&display=swap" rel="stylesheet">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <div class="container__panels">
            <div class="tasks panel">
                <h1 class="panel__headline">TASKS</h1>
                <button class="panel__button">CHECK TASKS</button>
            </div>
            <div class="events panel">
                <h1 class="panel__headline">EVENTS</h1>
                <button class=" panel__button">CHECK EVENTS</button>
            </div>
            <div class="reminder panel">
                <h1 class="panel__headline">REMINDERS</h1>
                <button class="panel__button" >CHECK REMINDERS</button>
            </div>
        </div>
    </div>
    <div class="modal">
        <button class="modal__exit">X</button>
    </div>
    <script src="classes.js"></script>
    <script src="script.js"></script>
</body>
</html>

CSS CODE:

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

html{
    font-size: 10px;
    font-family: 'Roboto', sans-serif;
}
body{
    position: relative;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}

.container{
    position: relative;
    width: 1200px;
}

.container__panels{
    display: flex;
    justify-content: space-between;
    align-items: center;
   
}

.panel{
    text-align: center;
    flex: 0 1 300px;
    background-color: #F1F1F1;
    height: 400px;
    border-radius: 16px;
    box-shadow: 0 0 10px 0 rgba(0,0,0,0.20);
    
    display: grid;
    grid-template: repeat(5, 1fr) / 1fr;
}

.panel__headline{
    margin: 1em 0;
    font-size: 2rem;
}

.panel__button{
    cursor: pointer;
    grid-row-start: 5;
    justify-self: center;
    width: 200px;
    height: 50px;
    border: 0;
    border-radius: 12px;
    background-color: #474554;
    color: #F1F1F1;
}

.panel__button:hover{
    color: #929297;
}

/* MODAL */

.modal{
    visibility: hidden;
    position: absolute;
    height: 600px;
    width: 50%;
    border: 1px solid black;
    width: 70%;
    background-color: #fff;
    border: 0;
    border-radius: 15px;
    box-shadow: 0 0 10px 1px rgba(0,0,0,0.1);
}

.modal__exit{
    cursor: pointer;
    position: absolute;
    right: 0;
    top: 0;
    padding: 1em 2em;
}

classes.js CODE:

"use strict"

class Modal {
    constructor(buttons, modal, closeBtn) {
        this.buttons = buttons;
        this.modal = modal;
        this.closeBtn = closeBtn;
    }

    showModal() {
        this.buttons.forEach(button => {
            button.addEventListener("click", () => {
                if (button.textContent === "CHECK TASKS") {
                    this.modal.style.visibility = "visible";
                }
            });
        });
    }

    closeModal() {
        if (this.closeBtn) {
            this.closeBtn.addEventListener("click", () => {
                this.modal.style.visibility = "hidden";
            });
        }
    }
}

script.js CODE:

"use strict";

const buttons = document.querySelectorAll(".panel__button");
const modal = document.querySelector(".modal");
const closeBtn = document.querySelector(".modal__exit");

const modalInstance = new Modal(buttons, modal, closeBtn);

buttons.forEach(button => {
    button.addEventListener("click", () => {
        modalInstance.showModal();
    });
});

if (closeBtn) {
    closeBtn.addEventListener("click", () => {
        modalInstance.closeModal();
    });
}

What should I do? I have no idea what to do, I am a begginer.