Returning form data in console after form submission

I am writing a form, and when this form is to be submitted, I want the resulting object of the form data to be printed in the console. I have tried to achieve this, but the console does not show the form data.

// get form element
const formElement = document.querySelector('form#event_form')

// convert the form to JSON
const getFormJSON = (form) => {
  const data = new FormData(form);
  return Array.from(data.keys()).reduce((result, key) => {
    result[key] = data.get(key);
    return result;
  }, {});
};


// handle the form submission event, prevent default form behaviour, check validity, convert form to JSON
const handler = (event) => {
  event.preventDefault();
  const valid = formElement.reportValidity();
  if (valid) {
    const result = getFormJSON(formElement);
    console.log(result)
  }
}

formElement.addEventListener("submit", handler)
<form name="event_form" id="event_form">
  <label for="event_summary">Event Summary:</label>
  <br>
  <input id="event_summary" type="text">
  <br>
  <br>
  <label for="event_location">Event Location:</label>
  <br>
  <input id="event_location" type="text">
  <br>
  <br>
  <label for="event_description">Event Description:</label>
  <br>
  <input id="event_description" type="text">
  <br>
  <br>
  <label for="start_time">Start Time:</label>
  <br>
  <input id="start_time" type="datetime-local">
  <br>
  <br>
  <label for="end_time">End Time:</label>
  <br>
  <input id="end_time" type="datetime-local">
  <br>
  <br>
  <button type="submit">Submit</button>
</form>

In the console, I do not see the form object logged. Is there a problem in my code?

Importing XML captions from String to Project

I’m writing a Premiere Pro plugin that grabs Premiere XML captions and I’m interested in importing them directly to the opened project using CsInterface.

But I had only found a way to do so by the importFiles function, while I haven’t found a way to save my XML into a File so I can not import it that way.

What can I do?
Thanks in advance everyone

Google Tag Manager script for dynamically generated page doesn’t work

I have a web page that is dynamically generated by a script (it’s a member dashboard). I’m trying to track when someone clicks on a dropdown which changes their selection of a care provider. Unfortunately I cannot alter the source code at all, I must come up with a solution using GTM alone.

I have this code:

<script>
console.log('Hello!!');
function dropdownListen(){
  var matOption = document.querySelector("mat-select[name=providerSelect] .mat-select-value span span");
   console.log(matOption);
      var callback = function(){
        //window.dataLayer = window.dataLayer || [];
        window.dataLayer.push({
          "event": "selectionMade"
        });
      };
      
  matOption.addEventListener("change", callback);
}
window.onload = dropdownListen();
</script>

The first Hello! logs in the console, but the second logging matOption returns null. I have confirmed that the selector works using this codepen (I just copied the code I’m trying to target into the HTML) https://codepen.io/pointnine/pen/zYMZvBy?editors=1111

I think it may have to do with the code running before the page is loaded? I can’t think of anything else. I currently have the custom HTML tag in GTM triggered on window load, but I’ve tried on DOM ready and page view which also doesn’t help. Any thoughts would be appreciated!

Cannot find module ‘workbox-webpack-plugin’

Suddenly my react project is crashed, everytime i use npm start i got below message:

PS C:able-pro-material-react> npm start 

> [email protected] start
> react-app-rewired start

node:internal/modules/cjs/loader:1080
  throw err;
  ^

Error: Cannot find module 'workbox-webpack-plugin'
Require stack:
- C:able-pro-material-reactconfig-overrides.js
- C:able-pro-material-reactnode_modulesreact-app-rewiredconfig-overrides.js
- C:able-pro-material-reactnode_modulesreact-app-rewiredscriptsstart.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1077:15)
    at Module._load (node:internal/modules/cjs/loader:922:27)
    at Module.require (node:internal/modules/cjs/loader:1143:19)
    at require (node:internal/modules/cjs/helpers:110:18)
    at Object.<anonymous> (C:able-pro-material-reactconfig-overrides.js:2:23)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Module._load (node:internal/modules/cjs/loader:960:12)
    at Module.require (node:internal/modules/cjs/loader:1143:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'C:\able-pro-material-react\config-overrides.js',
    'C:\able-pro-material-react\node_modules\react-app-rewired\config-overrides.js',
    'C:\able-pro-material-react\node_modules\react-app-rewired\scripts\start.js'
  ]
}

Node.js v18.16.1

npm install --save-dev webpack

i tried to use npm i -g webpack webpack-cli as well npm install –save-dev webpack but nothing changed.

Why pagination with filters does’nt work?

I’m creating ( for my portfolio ) a garage-website, you can search by filters if you want tu reduce the cars’choice.
Here is my problem: my filters function well. When i display all the vehicles without using filters my pagination is ok.
When i select a brand like peugeot for example, my filters function and displays only PEUGEOT cars, i got two pages porposed by my pagination (which is ok judging from my number’results et my pagination’s LIMIT) but when i click on page2, i come back to all the cars’selection and got a lot of pages in my pagination…

hers’s my script recherche.php

<link rel="stylesheet" href="./src/styles/style.css">
<?php
// Connexion à la base de données
$servername = "eu-cdbr-west-03.cleardb.net";
$username = "b3b93f93ef4872";
$password = "21163a70";
$dbname = "heroku_a9b8c2ad4d5e1ab";

try {
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Récupération des valeurs des filtres
    $marque = $_POST['marque'];
    $modele = $_POST['modele'];
    $annee = $_POST['annee'];
    $carburant = $_POST['carburant'];
    $boite_de_vitesse = $_POST['boite_de_vitesse'];
    $kilometres = $_POST['kilometres'];
    $prix = $_POST['prix'];
    $tri = $_POST['tri'];

    // Construction de la requête SQL
    $sql = "SELECT * FROM cars WHERE 1=1";

    $params = array();

    if (!empty($marque)) {
        $sql .= " AND marque = :marque";
        $params['marque'] = $marque;
    }

    if (!empty($modele)) {
        $sql .= " AND modele = :modele";
        $params['modele'] = $modele;
    }

    if (!empty($annee)) {
        $sql .= " AND annee = :annee";
        $params['annee'] = $annee;
    }

    if (!empty($carburant)) {
        $sql .= " AND carburant = :carburant";
        $params['carburant'] = $carburant;
    }

    if (!empty($boite_de_vitesse)) {
        $sql .= " AND boite_de_vitesse = :boite_de_vitesse";
        $params['boite_de_vitesse'] = $boite_de_vitesse;
    }

    if (!empty($kilometres)) {
        switch ($kilometres) {
            case 'de 0 à 50.000km':
                $sql .= " AND kilometres BETWEEN 0 AND 50000";
                break;
            case 'de 50.000 à 100.000 km':
                $sql .= " AND kilometres BETWEEN 50000 AND 100000";
                break;
            case 'de 100.000 à 150.000 km':
                $sql .= " AND kilometres BETWEEN 100000 AND 150000";
                break;
            case 'de 150.000 à 200.000 km':
                $sql .= " AND kilometres BETWEEN 150000 AND 200000";
                break;
            case '+ de 200.000 km':
                $sql .= " AND kilometres > 200000";
                break;
        }
    }

    if (!empty($prix)) {
        switch ($prix) {
            case 'de 0 à 10.000 €':
                $sql .= " AND prix BETWEEN 0 AND 10000";
                break;
            case 'de 10.000 à 20.000 €':
                $sql .= " AND prix BETWEEN 10000 AND 20000";
                break;
            case 'de 20.000 à 30.000 €':
                $sql .= " AND prix BETWEEN 20000 AND 30000";
                break;
            case 'de 30.000 à 40.000 €':
                $sql .= " AND prix BETWEEN 30000 AND 40000";
                break;
            case 'de 40.000 à 50.000 €':
                $sql .= " AND prix BETWEEN 40000 AND 50000";
                break;
            case 'de 50.000 à 75.000 €':
                $sql .= " AND prix BETWEEN 50000 AND 75000";
                break;
            case 'de 75.000 à 100.000 €':
                $sql .= " AND prix BETWEEN 75000 AND 100000";
                break;
            case '+ de 100.000 €':
                $sql .= " AND prix > 100000";
                break;
        }
    }

    if ($tri === "kilometres_asc") {
        $sql .= " ORDER BY kilometres ASC";
    } elseif ($tri === "kilometres_desc") {
        $sql .= " ORDER BY kilometres DESC";
    } elseif ($tri === "prix_asc") {
        $sql .= " ORDER BY prix ASC";
    } elseif ($tri === "prix_desc") {
        $sql .= " ORDER BY prix DESC";
    }

    // Compter le nombre total de résultats
    $stmtCount = $conn->prepare($sql);
    $stmtCount->execute($params);
    $totalResults = $stmtCount->rowCount();

    // Pagination
    $resultsPerPage = 12;
    $totalPages = ceil($totalResults / $resultsPerPage);
    $currentPage = isset($_POST['page']) ? $_POST['page'] : 1;
    $offset = ($currentPage - 1) * $resultsPerPage;

    // Ajouter la limitation et l'offset à la requête SQL
    $sql .= " LIMIT $offset, $resultsPerPage";

    // Préparation de la requête SQL
    $stmt = $conn->prepare($sql);

    // Exécution de la requête SQL avec les paramètres
    $stmt->execute($params);

    // Affichage des résultats
    if ($stmt->rowCount() > 0) {
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            echo "<div style=' border-radius: 20px 20px 20px 20px' class='container-fluid p-0 shadow containerCars'><a class='no-underline text-black' href='detailed_car.php?id=" . $row["id"] . "'>";
            // Récupération et décodage des images de la voiture
            $carId = $row["id"];
            $sqlImages = "SELECT image_base64 FROM images WHERE car_id = '$carId' LIMIT 1";
            $resultImages = $conn->query($sqlImages);

            if ($resultImages->rowCount() > 0) {
                echo "<div>";
                while ($rowImage = $resultImages->fetch(PDO::FETCH_ASSOC)) {
                    $imageData = $rowImage["image_base64"];
                    echo "<img class='img-fluid border-bottom' id='img-car' style='max-height: 200px; width: 348px; object-fit: cover; border-radius: 20px 20px 0 0' src='data:image/jpeg;base64," . $imageData . "' alt='Image voiture'>";
                }
                echo "</div>";
            }
            echo "<div style=' border-radius: 0 0 20px 20px' class='detailsCar border-0 text-start py-2 px-4 fs-6'><p class='text-center text-black fs-5'><b> " . $row["marque"] . ' ' . $row["modele"] . "</b></p>";
            echo "<p class='text-secondary m-0'>KM : <b> " . $row["kilometres"] . ' km' . "</b></p>";
            echo "<div class='my-2' style='border: 1px solid lightgrey'>   </div>";
            echo "<p class='text-secondary m-0'>Année : <b> " . $row["annee"] . "</b></p>";
            echo "<div class='my-2' style='border: 1px solid lightgrey'>   </div>";
            echo "<p class='text-secondary m-0'>Carburant : <b> " . $row["carburant"] . "</b></p>";
            echo "<div class='my-2' style='border: 1px solid lightgrey'>   </div>";
            echo "<p class='text-secondary m-0'>Boîte de vitesse : <b> " . $row["boite_de_vitesse"] . "</b></p>";
            echo "<div class='my-2' style='border: 1px solid lightgrey'>   </div>";
            echo "<p class='text-black text-center fs-5 m-0'><b> " . $row["prix"] . ' €' . "</b></p></div></a></div>";

        }
    } else {
        echo "Aucun résultat trouvé.";
    }

    // Affichage de la pagination
    echo "<div>";
    echo "<ul class='pagination'>";

    // Pagination
    $resultsPerPage = 12;
    $totalPages = ceil($totalResults / $resultsPerPage);
    $currentPage = isset($_POST['page']) ? $_POST['page'] : 1;
    $offset = ($currentPage - 1) * $resultsPerPage;
    
    if ($totalPages > 1) {

        // Récupérer les valeurs des filtres de recherche
    $marque = isset($_POST['marque']) ? $_POST['marque'] : '';
    $modele = isset($_POST['modele']) ? $_POST['modele'] : '';
    $annee = isset($_POST['annee']) ? $_POST['annee'] : '';
    $carburant = isset($_POST['carburant']) ? $_POST['carburant'] : '';
    $boite_de_vitesse = isset($_POST['boite_de_vitesse']) ? $_POST['boite_de_vitesse'] : '';
    $kilometres = isset($_POST['kilometres']) ? $_POST['kilometres'] : '';
    $prix = isset($_POST['prix']) ? $_POST['prix'] : '';
    $tri = isset($_POST['tri']) ? $_POST['tri'] : '';

    // Construction de l'URL avec les valeurs des filtres de recherche
    $url = "recherche.php?page=";
    
    if (!empty($marque)) {
        $url .= "&marque=" . urlencode($marque);
    }
    if (!empty($modele)) {
        $url .= "&modele=" . urlencode($modele);
    }
    if (!empty($annee)) {
        $url .= "&annee=" . urlencode($annee);
    }
    if (!empty($carburant)) {
        $url .= "&carburant=" . urlencode($carburant);
    }
    if (!empty($boite_de_vitesse)) {
        $url .= "&boite_de_vitesse=" . urlencode($boite_de_vitesse);
    }
    if (!empty($kilometres)) {
        $url .= "&kilometres=" . urlencode($kilometres);
    }
    if (!empty($prix)) {
        $url .= "&prix=" . urlencode($prix);
    }
    if (!empty($tri)) {
        $url .= "&tri=" . urlencode($tri);
    }

        if ($currentPage > 1) {
            $previous = $currentPage - 1;
            echo "<li class='page-item' id='1'><span class='page-link'>⟨⟨</span></li>"; ?>
            <li class='page-item' id="<?php echo $previous ?> "><span class='page-link'>⟨</span></li>
            <?php
        }

        for ($i = 1; $i <= $totalPages; $i++) {
            $active_class = "";
            if ($i == $currentPage) {
                $active_class = "active";
            }
            echo "<li class='page-item " . $active_class . "' id='" . $i . "'><span class='page-link'>" . $i . "</span></li>";
        }

        if ($currentPage < $totalPages) { ?>
            <li class='page-item' id="<?php echo ($currentPage + 1) ?>"><span class='page-link'>⟩</span></li>
            <li class='page-item' id="<?php echo $totalPages ?>"><span class='page-link'>⟩⟩</span></li>
            <?php
        }
    }
    echo "</ul>";
    echo "</div>";

} catch (PDOException $e) {
    echo "Échec de la connexion à la base de données : " . $e->getMessage();
}

$conn = null;
?>

here’s my pagination.js:

// Fonction pour effectuer une requête AJAX et mettre à jour les résultats de la pagination
function getPaginationResults(
  page,
  marque,
  modele,
  annee,
  carburant,
  boite_de_vitesse,
  kilometres,
  prix,
  tri
) {
  // Afficher l'animation de chargement ici si vous le souhaitez

  // Effectuer la requête AJAX
  $.ajax({
    url: "recherche.php",
    type: "POST",
    data: {
      page: page,
      marque: marque,
      modele: modele,
      annee: annee,
      carburant: carburant,
      boite_de_vitesse: boite_de_vitesse,
      kilometres: kilometres,
      prix: prix,
      tri: tri,
    }, // Envoyer le numéro de la page en paramètre
    success: function (response) {
      // Mettre à jour les résultats de la pagination
      $("#vehicules").html(response);

      // Masquer l'animation de chargement ici si vous l'avez affichée
    },
    error: function () {
      // Gérer les erreurs de la requête
      // Masquer l'animation de chargement ici si vous l'avez affichée
    },
  });
}

// Ajouter un écouteur d'événement sur les liens de pagination
$(document).on("click", ".page-item", function (e) {
  e.preventDefault(); // Empêcher le comportement par défaut des liens

  // Récupérer le numéro de la page à partir de l'attribut href du lien
  var page = $(this).attr("id");

  // Appeler la fonction pour effectuer la requête AJAX et mettre à jour les résultats de la pagination
  getPaginationResults(page);
});

and here’s my script.js:

document.getElementById("rechercher").addEventListener("click", function () {
  var marque = document.getElementById("marque").value;
  var modele = document.getElementById("modele").value;
  var annee = document.getElementById("annee").value;
  var carburant = document.getElementById("carburant").value;
  var boite_de_vitesse = document.getElementById("boite_de_vitesse").value;
  var kilometres = document.getElementById("kilometres").value;
  var prix = document.getElementById("prix").value;
  var tri = document.getElementById("tri").value;

  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status === 200) {
      document.getElementById("vehicules").innerHTML = xhr.responseText;
    }
  };

  var data =
    "marque=" +
    encodeURIComponent(marque) +
    "&modele=" +
    encodeURIComponent(modele) +
    "&annee=" +
    encodeURIComponent(annee) +
    "&carburant=" +
    encodeURIComponent(carburant) +
    "&boite_de_vitesse=" +
    encodeURIComponent(boite_de_vitesse) +
    "&kilometres=" +
    encodeURIComponent(kilometres) +
    "&prix=" +
    encodeURIComponent(prix) +
    "&tri=" +
    encodeURIComponent(tri);

  xhr.open("POST", "recherche.php", true);
  xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  xhr.send(data);
});

If someone could explain me what i did wrong and how i can correct it…
Thanx to you,
Colas

Array not returning with data [duplicate]

I’m trying to populate a table dynamically in VueJs 3. The idea for populating the rows is to call an API which will return the rows I need to render. What I have done so far the following

<tr v-for="row in this.rows(table.id)">
    <td v-for="header in this.headers(index)">
        {{ row[header.header] }}
    </td>
</tr>

The function rows is as follows:

rows: async function(tableID){

    let data = []
    await fetch("http://endpoint/" + String(tableID),{
        method: 'GET',
        headers: {
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Methods": "DELETE, POST, GET, OPTIONS",
            "Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With",
            "Content-Type": "text/plain",
            "Authorization": "Bearer " + access_token
        }
    })
    .then(response => response.json())
    .then(result => {
    result.forEach(row => {
        data.push(JSON.parse(row.row_data))
    })
})
return data
}, 

What’s happening is that when I return the data variable it comes out as empty and the table rows are never populated. I’m not sure if my approach is the best way to do this or not. Any advice/guidance is appreciated!

11ty images not generating on Netlify, working ok locally

I have a small 11ty site running on Netlify and using Decap CMS (formerly Netlify CMS). There’s an image field for uploading JPGs, and I’ve used 11ty Image to generate a Webp and an AVIF, then create a picture element.

The relevant parts of .eleventy.js are:

const Image = require("@11ty/eleventy-img");

module.exports = function(eleventyConfig) {
  eleventyConfig.addShortcode("image", async function(src, alt) {
    if(alt === undefined) {
      // You bet we throw an error on missing alt (alt="" works okay)
      throw new Error(`Missing `alt` on myImage from: ${src}`);
    }

    // Set up the image processing
    let metadata = await Image(src, {
      widths: [650],
      formats: ["jpeg", "webp", "avif"],
      urlPath: "/images/",
      outputDir: "./images/",
      sharpJpegOptions: {
        quality: 50
      }
    });

    // Get data for each format
    let jpegData = metadata.jpeg[metadata.jpeg.length - 1];
    let webpData = metadata.webp[metadata.webp.length - 1];
    let avifData = metadata.avif[metadata.avif.length - 1];

    return `<picture>
      <source srcset="${avifData.url}" type="image/avif">
      <source srcset="${webpData.url}" type="image/webp">
      <img src="${jpegData.url}" width="${jpegData.width}" height="${jpegData.height}" alt="${alt}" decoding="async">
      </picture>`;
  });
}

And in the template {% image poster, alt %} where poster is an image path and alt is a string.

That works fine locally, but for some reason I can’t fathom it’s not generating the images on Netlify, and I have to do a git pull, run it locally, then git push to deploy.

I did have it as an arrow function i.e. eleventyConfig.addShortcode("image", async (src, alt) => { but changing it to a function() hasn’t changed anything.

There was a service worker caching admin stuff that I’ve fixed to bypass any requests to /admin, and verified that.

Why isn’t it showing the result of the source code on the screen? [duplicate]

I’m with a project that has HTML, CSS, PHP and JavaScript code, as shown in file named 1.
When you double-click the home.php file, the computer automatically opens the code file in the code editor program, as shown in the file named 2.
When you try to open the home file.php through the browser, the source code of the file is displayed in the browser itself, as shown in the file named 3.

Please, what to do so that the browser displays the result of the source code, and does not display the source code?enter image description here
enter image description here
enter image description here

Node js – problem with query inside a loop

I got a problem with my query for inserting value in MySql, to add member to an intervention.

It works fine for a few run and after got “ER_LOCK_WAIT_TIMEOUT” and must reboot node js server.

I think the problem is my for loop , maybe i’m not using things properly.

Can someone help me figuring it out ?

app.post('/addmember', (request, response) => isLoggedin(request, settings => {
    let indicatif, time, distance, intervention, req;
    let length = request.body.data.length;
    intervention = request.body.id;

    req = "delete from participants where intervention = ? ;";
    connection.query(req, [intervention], (error, rows) => {
        if (error) {
            console.log(error);
        }
        for (x in request.body.data) {
            indicatif = request.body.data[x].username;
            time = request.body.data[x].time;
            distance = request.body.data[x].distance;

            req = "INSERT INTO participants set indicatif = ?, intervention = ? , time = ?, distance =?;";
            connection.query(req, [indicatif, intervention, time, distance], (error, rows) => {
                if (error) {
                    console.log(error);
                }
            });
        }

        req = "update interventions set nb_participants = ? where id = ? ;";
        connection.query(req, [taille, intervention], (error, rows) => {
            if (error) {
                console.log(error);
            }
        });
    });

    response.end();

}));

loading pn failed in tsc build

i have a tsc build react npm package.
And I want to use a png in my projekt.

Sadly i get an error when i try to build the projekt. Running Stroybook works fine. The Images also gets shown on the screen. Only when i try to build i reseive an error. So i think there is something wrong with the config. I Hope someone can help me fixing the config, so it will build successfully.

ERROR

npm run build

> [email protected] build
> tsdx build

@rollup/plugin-replace: 'preventAssignment' currently defaults to false. It is recommended to set this option to `true`, as the next major version will default this option to `true`.
@rollup/plugin-replace: 'preventAssignment' currently defaults to false. It is recommended to set this option to `true`, as the next major version will default this option to `true`.
✓ Creating entry file 1.2 secs
Error: Unexpected character '�' (Note that you need plugins to import files that are not JavaScript)

at D:2. repoportshare-frontend-libary-componentssrcimageplaceholder.png:1:0

1: ����►JFIF☺☺☺☺,☺,��VExifMM♦☺→♣☺>☺♣☺☺(♥☺☻☻‼♥☺☺☺,☺☺,☺��,Photoshop 3.08BIM♦♦∟☺Z♥��
�http://ns.adobe.com/xap/1.0/<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?>
   ^
2: <x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 10.10'>
3: <rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>

PS D:2. repoportshare-frontend-libary-components> 

tsconfig

{
  // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs
  "include": ["src", "types"],
  "compilerOptions": {
    "module": "esnext",
    "lib": ["dom", "esnext"],
    "importHelpers": true,
    // output .d.ts declaration files for consumers
    "declaration": true,
    // output .js.map sourcemap files for consumers
    "sourceMap": true,
    // match output dir to input dir. e.g. dist/index instead of dist/src/index
    "rootDir": "./src",
    // stricter type-checking for stronger correctness. Recommended by TS
    "strict": true,
    // linter checks for common issues
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    // use Node's module resolution algorithm, instead of the legacy TS one
    "moduleResolution": "node",
    // transpile JSX to React.createElement
    "jsx": "react",
    // interop between ESM and CJS modules. Recommended by TS
    "esModuleInterop": true,
    // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS
    "skipLibCheck": true,
    // error out if import and file system have a casing mismatch. Recommended by TS
    "forceConsistentCasingInFileNames": true,
    // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc`
    "noEmit": true,
    "resolveJsonModule": true, // Enable importing JSON files
    "allowSyntheticDefaultImports": true, // Enable synthetic default imports
    "allowUmdGlobalAccess": true, // Allow accessing UMD globals
    "types": ["node"], // Include the 'node' type definitions
    "target": "es2020",
    "baseUrl": ".",
    "paths": {
      "*": ["types/*"],
      "src/*": ["src/*"]
    },
    "downlevelIteration": true,
    "typeRoots": ["node_modules/@types"]
  }
}

tsdx.config.js

const scss = require('rollup-plugin-scss');
const { default: url } = require('@rollup/plugin-url');

module.exports = {
  rollup(config, options) {
    config.plugins.push(
      scss({
        output: true,
        sass: require('sass'),
        sassOptions: {
          includePaths: ['src'],
        },
        watch: ['src'],
      }),
      url({
        include: ['**/*.png'],
        limit: 0,
        fileName: '[name][extname]',
        destDir: options.dir, // Use options.dir to determine the destination directory
      })
    );
    return config;
  },
};

globals.d.ts

declare module '*.png';

.babelrc.json

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "chrome": 100
        }
      }
    ],
    "@babel/preset-typescript",
    "@babel/preset-react"
  ],
  "plugins": [
    "@babel/plugin-proposal-optional-chaining",
    "babel-plugin-inline-import"
  ]
}

package.json

{
  "version": "0.1.0",
  "license": "MIT",
  "main": "dist/index.js",
  "typings": "dist/index.d.ts",
  "files": [
    "dist",
    "src"
  ],
  "scripts": {
    "start": "tsdx watch",
    "build": "tsdx build",
    "test": "tsdx test --passWithNoTests",
    "lint": "tsdx lint",
    "prepare": "tsdx build",
    "size": "size-limit",
    "analyze": "size-limit --why",
    "storybook": "storybook dev -p 6006",
    "build-storybook": "storybook build"
  },
  "peerDependencies": {
    "react": ">=16"
  },
  "husky": {
    "hooks": {
      "pre-commit": "tsdx lint"
    }
  },
  "prettier": {
    "printWidth": 80,
    "semi": true,
    "singleQuote": true,
    "trailingComma": "es5"
  },
  "name": "portshare-frontend-libary-components",
  "author": "Leon Salenbacher",
  "module": "dist/portshare-frontend-libary-components.esm.js",
  "size-limit": [
    {
      "path": "dist/portshare-frontend-libary-components.cjs.production.min.js",
      "limit": "10 KB"
    },
    {
      "path": "dist/portshare-frontend-libary-components.esm.js",
      "limit": "10 KB"
    }
  ],
  "devDependencies": {
    "@babel/plugin-proposal-optional-chaining": "^7.21.0",
    "@babel/preset-env": "^7.22.5",
    "@babel/preset-react": "^7.22.5",
    "@babel/preset-typescript": "^7.22.5",
    "@rollup/plugin-url": "^8.0.1",
    "@size-limit/preset-small-lib": "^8.2.4",
    "@storybook/addon-essentials": "^7.0.21",
    "@storybook/addon-interactions": "^7.0.21",
    "@storybook/addon-links": "^7.0.21",
    "@storybook/blocks": "^7.0.21",
    "@storybook/react": "^7.0.21",
    "@storybook/react-webpack5": "^7.0.21",
    "@storybook/testing-library": "^0.0.14-next.2",
    "@types/react": "^18.2.14",
    "@types/react-dom": "^18.2.5",
    "babel-plugin-inline-import": "^3.0.0",
    "file-loader": "^6.2.0",
    "husky": "^8.0.3",
    "node-sass": "^9.0.0",
    "portshare-frontend-libary-objects": "^1.0.8",
    "prop-types": "^15.8.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-icons": "^4.9.0",
    "react-loading": "^2.0.3",
    "react-router-dom": "^6.13.0",
    "rollup-plugin-scss": "^4.0.0",
    "rollup-plugin-terser": "^7.0.2",
    "sass": "^1.63.6",
    "sass-loader": "^13.3.2",
    "size-limit": "^8.2.4",
    "storybook": "^7.0.21",
    "tsdx": "^0.14.1",
    "tslib": "^2.5.3",
    "url-loader": "^4.1.1"
  },
  "dependencies": {
    "react-simple-star-rating": "^5.1.7",
    "typescript": "^5.1.3"
  }
}

Javascript retrive option of a select set without a class or id

Hi I have the following code and try to retrieve the selected option of a list(for example Myoption2) created without a class or an id like the following:

<div class="form-group" data-type="service">
    <label>Mylabel</label>
    <div>
        <select>
            <option value="0">MyOption1</option>
            <option value="12">MyOption2</option>
            <option value="17">MyOption3</option>
            <option value="18">MyOption4</option>
        </select>
    </div>
</div>

I didn’t find the proper way to get this work with queryselector :[

This code is generated automatically by a wordpress plugin. So I didn’t find an easy way to edit it and define a class or an id.

Thank’s in advance for your help.

Unexpected token ‘c’, “class Book”… is not valid JSON error

I did a follow along tutorial where I created an simple application where the main functions would be to add and delete a book in the User Interface and Local Storage. I followed the tutorial line by line and even copy and pasted the creator of the tutorials code but I am still receiving an error that says Unexpected token ‘c’, “class Book”… is not valid JSON. The book is successfully added to user interface but is not persisting to local storage. I have provided my Html and JavaScript code below. Thanks in advance.

<!DOCTYPE html>

<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>My Booklist App</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="css/style.css">
        <link rel="stylesheet" href="css/all.css">
        <!-- Heading Font-->
        <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=Aboreto&display=swap" rel="stylesheet">
        <!-- Heading Font-->
        <link rel="stylesheet" href="css/bootstrap.min.css">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
    </head>
    <body>

<div class="container mt-4">
    <h1 class="display-4 text-center">
        <i class="fa-solid fa-book text-primary"></i></i> My<span class="text-primary">Book</span>List</h1>
      <form id="book-form">
        <div class="form-group">
          <label for="title">Title</label>
          <input type="text" id="title" class="form-control">
        </div>
        <div class="form-group">
          <label for="author">Author</label>
          <input type="text" id="author" class="form-control">
        </div>
        <div class="form-group">
          <label for="isbn">ISBN#</label>
          <input type="text" id="isbn" class="form-control">
        </div>
        <input type="submit" value="Add Book" class="btn btn-primary btn-block">
      </form>
      <table class="table table-striped mt-5">
        <thead>
          <tr>
            <th>Title</th>
            <th>Author</th>
            <th>ISBN#</th>
            <th></th>
          </tr>
        </thead>
        <tbody id="book-list"></tbody>
      </table>
  </div>

     
        
        <script src="js/main.js" async defer></script>
    </body>
</html>
// Book Class: Represents a Book
class Book {
    constructor(title, author, isbn) {
      this.title = title;
      this.author = author;
      this.isbn = isbn;
    }
  }
  
  // UI Class: Handle UI Tasks
  class UI {
    static displayBooks() {
      const books = Store.getBooks();
  
      books.forEach((book) => UI.addBookToList(book));
    }
  
    static addBookToList(book) {
      const list = document.querySelector('#book-list');
  
      const row = document.createElement('tr');
  
      row.innerHTML = `
        <td>${book.title}</td>
        <td>${book.author}</td>
        <td>${book.isbn}</td>
        <td><a href="#" class="btn btn-danger btn-sm delete">X</a></td>
      `;
  
      list.appendChild(row);
    }
  
    static deleteBook(el) {
      if(el.classList.contains('delete')) {
        el.parentElement.parentElement.remove();
      }
    }
  
    static showAlert(message, className) {
      const div = document.createElement('div');
      div.className = `alert alert-${className}`;
      div.appendChild(document.createTextNode(message));
      const container = document.querySelector('.container');
      const form = document.querySelector('#book-form');
      container.insertBefore(div, form);
  
      // Vanish in 3 seconds
      setTimeout(() => document.querySelector('.alert').remove(), 3000);
    }
  
    static clearFields() {
      document.querySelector('#title').value = '';
      document.querySelector('#author').value = '';
      document.querySelector('#isbn').value = '';
    }
  }
  
  // Store Class: Handles Storage
  class Store {
    static getBooks() {
      let books;
      if(localStorage.getItem('books') === null) {
        books = [];
      } else {
        books = JSON.parse(localStorage.getItem('books'));
      }
  
      return books;
    }
  
    static addBook(book) {
      const books = Store.getBooks();
      books.push(book);
      localStorage.setItem('books', JSON.stringify(books));
    }
  
    static removeBook(isbn) {
      const books = Store.getBooks();
  
      books.forEach((book, index) => {
        if(book.isbn === isbn) {
          books.splice(index, 1);
        }
      });
  
      localStorage.setItem('books', JSON.stringify(books));
    }
  }
  
  // Event: Display Books
  document.addEventListener('DOMContentLoaded', UI.displayBooks);
  
  // Event: Add a Book
  document.querySelector('#book-form').addEventListener('submit', (e) => {
    // Prevent actual submit
    e.preventDefault();
  
    // Get form values
    const title = document.querySelector('#title').value;
    const author = document.querySelector('#author').value;
    const isbn = document.querySelector('#isbn').value;
  
    // Validate
    if(title === '' || author === '' || isbn === '') {
      UI.showAlert('Please fill in all fields', 'danger');
    } else {
      // Instatiate book
      const book = new Book(title, author, isbn);
  
      // Add Book to UI
      UI.addBookToList(book);
  
      // Add book to store
      Store.addBook(book);
  
      // Show success message
      UI.showAlert('Book Added', 'success');
  
      // Clear fields
      UI.clearFields();
    }
  });
  
  // Event: Remove a Book
  document.querySelector('#book-list').addEventListener('click', (e) => {
    // Remove book from UI
    UI.deleteBook(e.target);
  
    // Remove book from store
    Store.removeBook(e.target.parentElement.previousElementSibling.textContent);
  
    // Show success message
    UI.showAlert('Book Removed', 'success');
  });

I tried copying and pasting the code from the tutorial I was working on hoping that if I missed something in my syntax it would be fixed but I still am receiving an error.

Error when installing expo in bare react native project. Build keeps failing

I am fairly new to mobile dev with react native. I started a bare react native project and I’m currently experiencing an error when trying to install expo, so I can use the expo camera library.
Following the docs:
1.https://docs.expo.dev/bare/installing-expo-modules/#usage
2.https://github.com/expo/expo/tree/sdk-48/packages/expo-camera)

I am currently stuck on step 1:

  1. I installed expo modules manually(since I used npx react init) using “npm install expo”
  2. I then followed all the steps detailed in link 1 to install expo by changing file content (files shown below)
    As directed by the docs, after changing my files, I did the following after changing the files:
npx expo install expo-constants
npx expo run:android

I received the following error:

› Building app...
Configuration on demand is an incubating feature.

FAILURE: Build failed with an exception.

* Where:
Build file 'C:UserssuleiDesktopReactNativeProjectsInstagramnode_modulesexpo-applicationandroidbuild.gradle' line: 40

* What went wrong:
A problem occurred evaluating project ':expo-application'.
> Could not set unknown property 'classifier' for task ':expo-application:androidSourcesJar' of type org.gradle.api.tasks.bundling.Jar.

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

See https://docs.gradle.org/8.0.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 4s
5 actionable tasks: 5 up-to-date
Error: C:UserssuleiDesktopReactNativeProjectsInstagramandroidgradlew.bat exited with non-zero code: 1
Error: C:UserssuleiDesktopReactNativeProjectsInstagramandroidgradlew.bat exited with non-zero code: 1
    at ChildProcess.completionListener (C:UserssuleiDesktopReactNativeProjectsInstagramnode_modules@expospawn-asyncbuildspawnAsync.js:52:23)
    at Object.onceWrapper (node:events:628:26)
    at ChildProcess.emit (node:events:513:28)
    at cp.emit (C:UserssuleiDesktopReactNativeProjectsInstagramnode_modules@expospawn-asyncnode_modulescross-spawnlibenoent.js:34:29)
    at maybeClose (node:internal/child_process:1091:16)
    at ChildProcess._handle.onexit (node:internal/child_process:302:5)
    ...
    at Object.spawnAsync [as default] (C:UserssuleiDesktopReactNativeProjectsInstagramnode_modules@expospawn-asyncbuildspawnAsync.js:17:21)        
    at spawnGradleAsync (C:UserssuleiDesktopReactNativeProjectsInstagramnode_modules@expoclibuildsrcstartplatformsandroidgradle.js:72:46)      
    at Object.assembleAsync (C:UserssuleiDesktopReactNativeProjectsInstagramnode_modules@expoclibuildsrcstartplatformsandroidgradle.js:52:18)  
    at runAndroidAsync (C:UserssuleiDesktopReactNativeProjectsInstagramnode_modules@expoclibuildsrcrunandroidrunAndroidAsync.js:31:24)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

build.gradle file in android directory:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext {
        buildToolsVersion = "33.0.0"
        minSdkVersion = 21
        compileSdkVersion = 33
        targetSdkVersion = 33

        // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
        ndkVersion = "23.1.7779620"
    }
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath("com.android.tools.build:gradle")
        classpath("com.android.tools.build:gradle:7.4.1")
        classpath("com.facebook.react:react-native-gradle-plugin")
    }
}
allprojects {
    repositories {
        jcenter() {
            content {
                includeModule("com.yqritc", "android-scalablevideoview")
            }
        }
    }
}

settings.gradle file:

rootProject.name = ‘Instagram’
apply from: file(“../node_modules/@react-native-community/cli-platform-android/native_modules.gradle”); applyNativeModulesSettingsGradle(settings)
include ‘:app’
includeBuild(‘../node_modules/@react-native/gradle-plugin’)
apply from: new File([“node”, “–print”, “require.resolve(‘expo/package.json’)”].execute(null, rootDir).text.trim(), “../scripts/autolinking.gradle”)
useExpoModules()


MainActivity.java file:

package com.instagram;
import expo.modules.ReactActivityDelegateWrapper;

import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactActivityDelegate;

public class MainActivity extends ReactActivity {

  /**
   * Returns the name of the main component registered from JavaScript. This is used to schedule
   * rendering of the component.
   */
  @Override
  protected ReactActivityDelegate createReactActivityDelegate() {
        return new ReactActivityDelegateWrapper(this, BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, new DefaultReactActivityDelegate(
            this,
            getMainComponentName(),
        // If you opted-in for the New Architecture, we enable the Fabric Renderer.
            DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled
            // If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18).
            DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled

));
}
}

MainApplication.java file

package com.instagram;
import android.content.res.Configuration;
import expo.modules.ApplicationLifecycleDispatcher;
import expo.modules.ReactNativeHostWrapper;

import android.app.Application;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactNativeHost;
import com.facebook.soloader.SoLoader;
import java.util.List;

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost =
      new ReactNativeHostWrapper(this, new DefaultReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
          return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
          @SuppressWarnings("UnnecessaryLocalVariable")
          List<ReactPackage> packages = new PackageList(this).getPackages();
          // Packages that cannot be autolinked yet can be added manually here, for example:
          // packages.add(new MyReactNativePackage());
          return packages;
        }

        @Override
        protected String getJSMainModuleName() {
          return "index";
        }

        @Override
        protected boolean isNewArchEnabled() {
          return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
        }

        @Override
        protected Boolean isHermesEnabled() {
          return BuildConfig.IS_HERMES_ENABLED;
        }
      });

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
    if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
      // If you opted-in for the New Architecture, we load the native entry point for this app.
      DefaultNewArchitectureEntryPoint.load();
    }
    ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
    ApplicationLifecycleDispatcher.onApplicationCreate(this);
      }
     
      @Override
      public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig);
  }
}

My package.json file:

{
  "name": "Instagram",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "lint": "eslint .",
    "start": "react-native start",
    "test": "jest"
  },
  "dependencies": {
    "expo": "^48.0.19",
    "react": "18.2.0",
    "react-native": "0.72.0",
    "react-native-image-picker": "^5.6.0",
    "react-native-vector-icons": "^9.2.0",
    "react-native-video": "^5.2.1",
    "expo-constants": "~14.2.1"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@babel/preset-env": "^7.20.0",
    "@babel/runtime": "^7.20.0",
    "@react-native/eslint-config": "^0.72.2",
    "@react-native/metro-config": "^0.72.6",
    "@tsconfig/react-native": "^3.0.0",
    "@types/metro-config": "^0.76.3",
    "@types/react": "^18.0.24",
    "@types/react-native-vector-icons": "^6.4.13",
    "@types/react-native-video": "^5.0.14",
    "@types/react-test-renderer": "^18.0.0",
    "babel-jest": "^29.2.1",
    "eslint": "^8.19.0",
    "jest": "^29.2.1",
    "metro-react-native-babel-preset": "0.76.5",
    "prettier": "^2.4.1",
    "react-test-renderer": "18.2.0",
    "typescript": "4.8.4"
  },
  "engines": {
    "node": ">=16"
  }
}

I have tried all the steps listed in the docs but I am unsure of what I am missing. Need help

D3 : Custom projection with tiles (Waterman Butterfly)

I’m looking for a Waterman Butterfly map with imagery projection (Esri.WorldImagery).
Waterman Butterfly map

Im a beginner in javascript and after searching for somes projects and simply replace the projection used didn’t work :
Test1
Test2

I have also try to adapt Mbostock converter used in this post
-> index.html source.jpeg

<!DOCTYPE html>
<meta charset="utf-8">
<style>
  body {
    background: #222;
  }
</style>
<body>
  <script src="https://d3js.org/d3.v5.min.js"></script>
  <script src="https://d3js.org/d3-geo.v1.min.js"></script>
  <script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>
  <script>
 
    var width = 960,
        height = 500;
 
    var projection = d3.geoPolyhedralWaterman();
 
    var path = d3.geoPath()
        .projection(projection);
 
    var canvas = d3.select("body").append("canvas")
        .attr("width", width)
        .attr("height", height);
 
    var context = canvas.node().getContext("2d");
 
    var image = new Image;
    image.onload = onload;
    image.src = "source.jpg";
 
    function onload() {
      var dx = image.width,
          dy = image.height;
 
      context.drawImage(image, 0, 0, dx, dy);
 
      var sourceData = context.getImageData(0, 0, dx, dy).data,
          target = context.createImageData(width, height),
          targetData = target.data;
 
      for (var y = 0, i = -1; y < height; ++y) {
        for (var x = 0; x < width; ++x) {
          var p = projection.invert([x, y]), λ = p[0], φ = p[1];
          if (λ > 180 || λ < -180 || φ > 90 || φ < -90) { i += 4; continue; }
          var q = ((90 - φ) / 180 * dy | 0) * dx + ((180 + λ) / 360 * dx | 0) << 2;
          targetData[++i] = sourceData[q];
          targetData[++i] = sourceData[++q];
          targetData[++i] = sourceData[++q];
          targetData[++i] = 255;
        }
      }
 
      context.clearRect(0, 0, width, height);
      context.putImageData(target, 0, 0);
    }
  </script>
</body>
</html>

But again without success,

If anyone would like to look into this, I’d be very grateful.