Datatable support RTL on PDF export

I’m Using Jquery DataTable and I’m working on RTL Version, every thing is OK but when I want to export on PDF every Arabic Letters change to [], Please help me..

 $("#table_id").DataTable({
     dom: "Bfrtip",
     buttons: ["excel", "pdf", "print"],
     searching: false,
     paging: false,
 });

it works for export to excel and print but the issue is only in PDF.

How can I run index.js without getting this error?

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

Error: Cannot find module ‘../build/Release/canvas.node’
Require stack:

  • /Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas/lib/bindings.js
  • /Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas/lib/canvas.js
  • /Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas/index.js
  • /Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/src/main.js
  • /Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/index.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:999:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object. (/Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas/lib/bindings.js:3:18)
    at Module._compile (node:internal/modules/cjs/loader:1097:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1151:10)
    at Module.load (node:internal/modules/cjs/loader:975:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:999:19) {
    code: ‘MODULE_NOT_FOUND’,
    requireStack: [
    ‘/Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas/lib/bindings.js’,
    ‘/Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas/lib/canvas.js’,
    ‘/Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas/index.js’,
    ‘/Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/src/main.js’,
    ‘/Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/index.js’
    ]
    }

Node.js v17.6.0
turcuoctavian@Turcus-MacBook-Pro hashlips_art_engine % yarn index.js
yarn run v1.22.17
warning ../../../package.json: No license field
error Command “index.js” not found.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
turcuoctavian@Turcus-MacBook-Pro hashlips_art_engine % npm instal
l canvas
npm notice Beginning October 4, 2021, all connections to the npm registry – including for package installation – must use TLS 1.2 or higher. You are currently using plaintext http to connect. Please visit the GitHub blog for more information: https://github.blog/2021-08-23-npm-registry-deprecating-tls-1-0-tls-1-1/
npm notice Beginning October 4, 2021, all connections to the npm registry – including for package installation – must use TLS 1.2 or higher. You are currently using plaintext http to connect. Please visit the GitHub blog for more information: https://github.blog/2021-08-23-npm-registry-deprecating-tls-1-0-tls-1-1/
npm ERR! code 1
npm ERR! path /Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas
npm ERR! command failed
npm ERR! command sh -c node-pre-gyp install –fallback-to-build
npm ERR! Failed to execute ‘/Users/turcuoctavian/.nvm/versions/node/v17.6.0/bin/node /Users/turcuoctavian/.nvm/versions/node/v17.6.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js configure –fallback-to-build –module=/Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas/build/Release/canvas.node –module_name=canvas –module_path=/Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas/build/Release –napi_version=8 –node_abi_napi=napi –napi_build_version=0 –node_napi_label=node-v102’ (1)
npm ERR! node-pre-gyp info it worked if it ends with ok
npm ERR! node-pre-gyp info using [email protected]
npm ERR! node-pre-gyp info using [email protected] | darwin | arm64
npm ERR! node-pre-gyp info check checked for “/Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas/build/Release/canvas.node” (not found)
npm ERR! node-pre-gyp http GET https://github.com/Automattic/node-canvas/releases/download/v2.9.0/canvas-v2.9.0-node-v102-darwin-unknown-arm64.tar.gz
npm ERR! node-pre-gyp ERR! install response status 404 Not Found on https://github.com/Automattic/node-canvas/releases/download/v2.9.0/canvas-v2.9.0-node-v102-darwin-unknown-arm64.tar.gz
npm ERR! node-pre-gyp WARN Pre-built binaries not installable for [email protected] and [email protected] (node-v102 ABI, unknown) (falling back to source compile with node-gyp)
npm ERR! node-pre-gyp WARN Hit error response status 404 Not Found on https://github.com/Automattic/node-canvas/releases/download/v2.9.0/canvas-v2.9.0-node-v102-darwin-unknown-arm64.tar.gz
npm ERR! gyp info it worked if it ends with ok
npm ERR! gyp info using [email protected]
npm ERR! gyp info using [email protected] | darwin | arm64
npm ERR! gyp info ok
npm ERR! gyp info it worked if it ends with ok
npm ERR! gyp info using [email protected]
npm ERR! gyp info using [email protected] | darwin | arm64
npm ERR! gyp info find Python using Python version 3.8.9 found at “/Library/Developer/CommandLineTools/usr/bin/python3”
npm ERR! gyp info spawn /Library/Developer/CommandLineTools/usr/bin/python3
npm ERR! gyp info spawn args [
npm ERR! gyp info spawn args ‘/Users/turcuoctavian/.nvm/versions/node/v17.6.0/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py’,
npm ERR! gyp info spawn args ‘binding.gyp’,
npm ERR! gyp info spawn args ‘-f’,
npm ERR! gyp info spawn args ‘make’,
npm ERR! gyp info spawn args ‘-I’,
npm ERR! gyp info spawn args ‘/Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas/build/config.gypi’,
npm ERR! gyp info spawn args ‘-I’,
npm ERR! gyp info spawn args ‘/Users/turcuoctavian/.nvm/versions/node/v17.6.0/lib/node_modules/npm/node_modules/node-gyp/addon.gypi’,
npm ERR! gyp info spawn args ‘-I’,
npm ERR! gyp info spawn args ‘/Users/turcuoctavian/Library/Caches/node-gyp/17.6.0/include/node/common.gypi’,
npm ERR! gyp info spawn args ‘-Dlibrary=shared_library’,
npm ERR! gyp info spawn args ‘-Dvisibility=default’,
npm ERR! gyp info spawn args ‘-Dnode_root_dir=/Users/turcuoctavian/Library/Caches/node-gyp/17.6.0’,
npm ERR! gyp info spawn args ‘-Dnode_gyp_dir=/Users/turcuoctavian/.nvm/versions/node/v17.6.0/lib/node_modules/npm/node_modules/node-gyp’,
npm ERR! gyp info spawn args ‘-Dnode_lib_file=/Users/turcuoctavian/Library/Caches/node-gyp/17.6.0/<(target_arch)/node.lib’,
npm ERR! gyp info spawn args ‘-Dmodule_root_dir=/Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas’,
npm ERR! gyp info spawn args ‘-Dnode_engine=v8’,
npm ERR! gyp info spawn args ‘–depth=.’,
npm ERR! gyp info spawn args ‘–no-parallel’,
npm ERR! gyp info spawn args ‘–generator-output’,
npm ERR! gyp info spawn args ‘build’,
npm ERR! gyp info spawn args ‘-Goutput_dir=.’
npm ERR! gyp info spawn args ]
npm ERR! /bin/sh: pkg-config: command not found
npm ERR! gyp: Call to ‘pkg-config pixman-1 –libs’ returned exit status 127 while in binding.gyp. while trying to load binding.gyp
npm ERR! gyp ERR! configure error
npm ERR! gyp ERR! stack Error: gyp failed with exit code: 1
npm ERR! gyp ERR! stack at ChildProcess.onCpExit (/Users/turcuoctavian/.nvm/versions/node/v17.6.0/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:259:16)
npm ERR! gyp ERR! stack at ChildProcess.emit (node:events:527:28)
npm ERR! gyp ERR! stack at Process.ChildProcess._handle.onexit (node:internal/child_process:291:12)
npm ERR! gyp ERR! System Darwin 21.3.0
npm ERR! gyp ERR! command “/Users/turcuoctavian/.nvm/versions/node/v17.6.0/bin/node” “/Users/turcuoctavian/.nvm/versions/node/v17.6.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js” “configure” “–fallback-to-build” “–module=/Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas/build/Release/canvas.node” “–module_name=canvas” “–module_path=/Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas/build/Release” “–napi_version=8” “–node_abi_napi=napi” “–napi_build_version=0” “–node_napi_label=node-v102”
npm ERR! gyp ERR! cwd /Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas
npm ERR! gyp ERR! node -v v17.6.0
npm ERR! gyp ERR! node-gyp -v v8.4.1
npm ERR! gyp ERR! not ok
npm ERR! node-pre-gyp ERR! build error
npm ERR! node-pre-gyp ERR! stack Error: Failed to execute ‘/Users/turcuoctavian/.nvm/versions/node/v17.6.0/bin/node /Users/turcuoctavian/.nvm/versions/node/v17.6.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js configure –fallback-to-build –module=/Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas/build/Release/canvas.node –module_name=canvas –module_path=/Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas/build/Release –napi_version=8 –node_abi_napi=napi –napi_build_version=0 –node_napi_label=node-v102’ (1)
npm ERR! node-pre-gyp ERR! stack at ChildProcess. (/Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/@mapbox/node-pre-gyp/lib/util/compile.js:89:23)
npm ERR! node-pre-gyp ERR! stack at ChildProcess.emit (node:events:527:28)
npm ERR! node-pre-gyp ERR! stack at maybeClose (node:internal/child_process:1090:16)
npm ERR! node-pre-gyp ERR! stack at Process.ChildProcess._handle.onexit (node:internal/child_process:302:5)
npm ERR! node-pre-gyp ERR! System Darwin 21.3.0
npm ERR! node-pre-gyp ERR! command “/Users/turcuoctavian/.nvm/versions/node/v17.6.0/bin/node” “/Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/.bin/node-pre-gyp” “install” “–fallback-to-build”
npm ERR! node-pre-gyp ERR! cwd /Users/turcuoctavian/Desktop/NFT generator/hashlips_art_engine/node_modules/canvas
npm ERR! node-pre-gyp ERR! node -v v17.6.0
npm ERR! node-pre-gyp ERR! node-pre-gyp -v v1.0.6
npm ERR! node-pre-gyp ERR! not ok

npm ERR! A complete log of this run can be found in:
npm ERR! /Users/turcuoctavian/.npm/_logs/2022-02-26T11_41_40_833Z-debug-0.log
turcuoctavian@Turcus-MacBook-Pro hashlips_art_engine % npm index.js
Unknown command: “index.js”

Error with async code design. UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT],

I am facing an error with node/express. I am assuming the issue is with my asynchronous code design.

Output:
Success in container

Expected Output:
Success in container..
Success in Uploading…

Error: (node:18364) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch()

DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Code:

const express = require("express");
const multer = require("multer");
const AuthReq = require("../middleWare/AuthReq");
require("dotenv").config();
const Azure_Storage_Connection_String = process.env.Azure_Connection_String;
const { BlobServiceClient } = require("@azure/storage-blob");

const Router = express.Router();

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, "uploads");
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + "-" + file.originalname);
  },
});

const upload = multer({ storage: storage });

Router.post("/profile", AuthReq, upload.single("profile"), async (req, res) => {
  const file = req.file;

  const blobServiceClient = BlobServiceClient.fromConnectionString(
    Azure_Storage_Connection_String
  );

  const containerName = req.user._id;

  const ContainerClient = blobServiceClient.getContainerClient(containerName);

  try {
    const containerResponse = await ContainerClient.create();
  } catch (err) {
    return res.status(400).send("Error while sending image");
  }

  res.send("Success in container");

  const contentType = file.mimetype;

  const filePath = file.path;

  const blobName = file.filename + contentType;

  const blockBlobClient = ContainerClient.getBlockBlobClient(blobName);

  try {
    const uploadBlobResponse = await blockBlobClient.uploadFile(filePath);
  } catch (err) {
    return res.status(400).send("Error while sending image");
  }

  res.send("Success in Uploading...");
});

module.exports = Router;

How can i use localstorage array in different component

i want to show “favorites” item in my favorites component. but since i can’t pass postList component to favorites component i don’t know how to do it.

basically this is what i get from this coding. but i want to show favorite items in another page/component: enter image description here

Home.js


    import React, { useState, useEffect } from "react";
    import { getDocs, collection, deleteDoc, doc } from "firebase/firestore";
    import { db, auth } from "../../firebase";
    import { Link } from "react-router-dom";
    import Sidebar from "../Sidebar/Sidebar";
    import "./Home.css";
    import PostList from "./PostList";

    const Home = ({ isAuth, setIsAuth }) => {
      const [postLists, setPostList] = useState([]);
      const postsCollectionRef = collection(db, "posts");
      const [favorites, setFavorites] = useState(localStorage.getItem("dam"));

      useEffect(() => {
        const getPosts = async () => {
          const data = await getDocs(postsCollectionRef);
          setPostList(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
        };

        getPosts();
      }, []);

      useEffect(() => {
        const localData = localStorage.getItem("dam") ?? [];
        setFavorites(localData);
      }, [setFavorites]);

      const addFavorite = (favorite) => {
        setFavorites((prevfavorites) => [...prevfavorites, favorite]);

        localStorage.setItem("dam", JSON.stringify(favorites));
      };

      return (
        <div className="containers">
          <div className="sidebar">
            <Sidebar isAuth={isAuth} setIsAuth={setIsAuth} />
            <div className="centered">
              <div className="bordered">
                <button id="ado">
                  <Link to="/createpost">+ Add API</Link>
                </button>
              </div>

              <div className="new-container">
                {postLists?.map((post) => {
                  return (
                    <>
                      <PostList
                        post={post}
                        addFavorite={addFavorite}
                        key={post.id}
                      />
                    </>
                  );
                })}
              </div>
            </div>
            <div className="another">
              <h2>FAVORITE ITEMS</h2>
              {postLists
                .filter((post) => favorites.includes(post.id))
                .map((post) => (
                  <PostList post={post} addFavorite={addFavorite} key={post.id} />
                ))}
            </div>
          </div>
        </div>
      );
    };

    export default Home;

PostList.js


    import React from "react";

    const PostList = ({ post, addFavorite }) => {
      const { linkin, title, imageURL, photoURL, name, id } = post;

      return (
        <>
          <div>
            <div className="post">
              <div className="postimage">
                <div className="del"></div>

                <div className="images">
                  <a href={linkin}>
                    <p className="ss">{title}</p>

                    <img src={imageURL} id="img-photo" />
                  </a>
                  <div className="uploader">
                    <img src={photoURL} />

                    <p>by {name}</p>
                  </div>
                  {addFavorite && (
                    <div className="butons">
                      <button onClick={() => addFavorite(id)} id="favori">
                        +
                      </button>
                    </div>
                  )}
                </div>
              </div>
            </div>
          </div>
        </>
      );
    };

    export default PostList;


and a empty Favorites.js component.

Favorites.js

favorites here...

Strapi POST api for content-type with relational fields

Every time I try to create an order via /api/order it gives me 400 (Bad request), there doesn’t seem to be a proper clear explanation anywhere on how to create records with relational fields, the only one I found close to what I needed was this: Strapi "Create an entry" docs with relational fields

So supposedly I should use an id or a list of ids depending on the type of relation, but it still gives me 400 Bad request with no explanation in the response.

My order content-type looks like this:

Order content-type

User is a Many-to-One relationship, so a user can have many orders, but there can only be one user per order, and products is One-to-Many, so an order can have many products

This is what my API call looks like:

    await axios.post(
      `${baseUrl}/api/orders`,
      {
        products: [9],
        total: 320,
        user: 42
      }
    );

The products and user ids are exactly the ones I have in the database and authentication is not the problem.

Please help me understand what I’m doing wrong and how I should be creating records with relational fields. Thanks

How to leave trail in my sketch without deleting the background in p5js?

I would like to leave line trails at each of the corners of the rectangles. I have tried createGraphics to add an extra canvas where I want to leave the trails but it’s just doesn’t work.

I purposefully rotate the rectangle with cosine. My assignment forbids to use the rotate function.

I followed this tutorial: https://www.youtube.com/watch?v=TaluaAD9MKA

The Sketch:

Without createGraphics: https://editor.p5js.org/plaszlo/sketches/W6Bq6zAI3

With createGraphics: https://editor.p5js.org/plaszlo/sketches/WQhPN5e7F

Thank you

Node js fs is showing undefined on console.log

I was working on a Next js blog,
I have completed the frontend and I was making backend using the next js

./pages/api

I made a file

./pages/api/blogs.js

I made some json files in ./data folder as dummy data

./data/hello.json
{
"title" : "This is hello",
"description" : "This is description",
"content" : "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iusto quasi error cumque iure tempore officiis quaerat rerum delectus hic reprehenderit. Iure, eveniet repudiandae. Consequuntur obcaecati eius sequi similique officia beatae quibusdam blanditiis."
}

I write this code in ./pages/api/blogs.js

import * as fs from 'fs'

export default function handler(req, res) {
    fs.readFile("../../data/hello.json", (err,data)=>{
        console.log(data)
    })
    res.status(200).json({"name" : "Shivam Bhai"})
}

but my server console is showing undefined.
how do I fix this problem?

Loop on element and extract all child properties

I have the attached HTML
I would like a javascript code to execute on chrome console that
1 – go on all the

enter image description here

that have a child go recursively run on child and extract property

the output that i woudl like to have is


id="preview:section:subSectionF55group13:subSectionTabF55group13" --> class="ui-accordion ui-widget ui-helper-reset ui-hidden-container" --> data-form-designer-id="" --> "Group 13 Parties"
id="preview:section:subSectionF55group13:subSectionF55-10"--> class="ui-accordion ui-widget ui-helper-reset ui-hidden-container" --> data-form-designer-id="" --> "(05) [3/17] Declarant"
id="preview:section:subSectionF55group13:subSectionF55-10:F55-10-2" ---> class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all other ui-state-hover" --> data-form-designer-id="F55-10-2" --> role="textbox" --> label="(05 016) [3/17a] Name"
id="preview:section:subSectionF55group13:subSectionF55-10:F55-10-3" ---> class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all other ui-state-hover" --> data-form-designer-id="F55-10-3" --->  role="textbox" --> label="(05 017) [3/18] Declarant identification No. "

the label is on the span element onthe previus object

Migrating to Bootstrap v4 caused a table to disappear

I wrote my code in Bootstrap v3, however, upon realising that it doesn’t support Spinners and many of the CSS elements I’ve envisioned didn’t have the style that I wanted, I want to switch to Bootstrap v4. I added all of the required scripts / css links to the head, however I noticed that one whole table from my code has frankly just disappeared. And I have no idea why. The table is on a separate html element, and works in Bootstrap v3 but not sure why it’s not displaying with v4.

Code:

main2.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"></script>

  <style>
  </style>
</head>
<body>
  <div id="header" style="background-color: white; width:100%; height:auto; position:fixed;">
    <p id="statusText">Preparing supermarkets from Google Drive...</p>

    <div id="form-group">
      <input type="text" class="form-control" id="searchInput" placeholder="Search by Name or ID of Supermarket"/> 
    </div> 
  </div>

    <!-- <div class="d-flex justify-content-center align-items-center" style="visibility:hidden;">
    <div class="spinner-border" id="spinner" role="status">
    </div> -->
  </div>

    <div class="container">
      <div id="addsupermarket" style="" class="">
      </div>

  <div id="foot" style="background-color:white; width:100%; height:auto; position:fixed; top:447px;">
    <button type="button" class="btn btn-primary" style="float:right;" id="btnAdd">Add Supermarkets</button>
  </div>




  
  <script>  
    var data;
    var checkedItems = new Map();

    function loadView(options) {
      var id = typeof options.id === "undefined" ? "addsupermarket" : options.id;
      var cb = typeof options.callback === "undefined" ? function(){} : options.callback;
      google.script.run.withSuccessHandler(function(html) {
        document.getElementById("addsupermarket").innerHTML = html;
        typeof options.params === "undefined" ? cb() : cb(options.params);

      })[options.func]();
    }
    function setDataForSearch() {
      checkedItems = new Map();
      showSpinner();
      document.getElementById("statusText").innerHTML = "Loading..."
      google.script.run.withSuccessHandler(function(dataReturned) {
        data = dataReturned.slice();
        var searchResultsBox = document.getElementById("searchResults");
        var templateBox = document.getElementById("rowTemplate");
        var template = templateBox.content;

        data.forEach(function(r) {
        var tr = template.cloneNode(true);
        var supermarketCheckColumn = tr.querySelector(".supermarketCheck");
        var supermarketNameColumn = tr.querySelector(".supermarketName");
        var supermarketIDColumn = tr.querySelector(".supermarketID");
        var supermarketStatusColumn = tr.querySelector(".supermarketStatus");
        var supermarketCheckbox = tr.querySelector(".supermarketCheckbox");
        supermarketNameColumn.textContent = r[0];
        supermarketIDColumn.textContent = r[1];
        supermarketStatusColumn.textContent = r[2];
        supermarketCheckbox.dataset.supermarketID = r[1];
        searchResultsBox.appendChild(tr);
        });
        document.getElementById("statusText").innerHTML = "Found " + data.length + " results";
        hideSpinner();
      }).getDataForSearch();
    }

    function loadAddSupermarketView() {
      loadView({func: "loadAddSupermarketView", callback: setDataForSearch});
    }
    loadAddSupermarketView();
    document.getElementById("searchInput").addEventListener("input", inputEventHandler);
    function inputEventHandler(e) {
      if (e.target.matches("#searchInput")) {
        search();
      }
    }

    function showSpinner() {
      document.getElementById("spinner").style.visibility = "visible";
    }

    function hideSpinner() {
      document.getElementById("spinner").style.visibility = "hidden";
    }
    
    function search() {
      var searchInput = document.getElementById("searchInput").value;
      var resultsArray = data.filter(function(r) {
        return (r[0].toString().toLowerCase().indexOf(searchInput.toString().toLowerCase()) !== -1 || (r[1].toString().indexOf(searchInput.toString()) !== -1));
      });
      document.getElementById("statusText").innerHTML = "Loading..."
      var searchResultsBox = document.getElementById("searchResults");
      var templateBox = document.getElementById("rowTemplate");
      var template = templateBox.content;
      searchResultsBox.innerHTML = "";
      resultsArray.forEach(function(r) {
        var tr = template.cloneNode(true);
        var supermarketCheckbox = tr.querySelector(".supermarketCheckbox");
        var supermarketCheckColumn = tr.querySelector(".supermarketCheck");
        var supermarketNameColumn = tr.querySelector(".supermarketName");
        var supermarketIDColumn = tr.querySelector(".supermarketID");
        var supermarketStatusColumn = tr.querySelector(".supermarketStatus");
        supermarketCheckbox.dataset.supermarketID = r[1];
        supermarketNameColumn.textContent = r[0];
        supermarketIDColumn.textContent = r[1];
        supermarketStatusColumn.textContent = r[2];
        searchResultsBox.appendChild(tr);
        });
        document.getElementById("statusText").innerHTML = "Found " + resultsArray.length + " results";      
    }
  </script>
</body>
</html>

addsupermarket.html (which contains the table)

<table class="table">
  <thead>
    <tr>
      <th scope="col">Add?</th>
      <th scope="col">Name</th>
      <th scope="col">ID</th>
      <th scope="col">Status</th>
    </tr>
  </thead>
  <tbody id="searchResults">
  </tbody>
</table>

HTML Form submit for Radio Buttons

I have a basic HTML form that takes input from the user about his age, gender, dob, email and contact number. I save it into the local storage as employeeData by making it an object in an array. [{},{},{}]. I also add a User_id that is calculated by a random function generator and display it using the Javascript. An example is mentioned below.

[
    {
        "U_Id": "1a9f1268-9c74-4cfb-971c-f595cb4a40e1",
        "Name": "dsgfdsfds",
        "Gender": "Male",
        "Dob": "2022-02-04",
        "Email": "[email protected]",
        "Tel": "9958111111",
        "Hobbies": [
            "Coding"
        ]
    },
    {
        "U_Id": "d7e5b305-4604-4831-b168-96136a7b4ea5",
        "Name": "dghdghdhddh",
        "Gender": "Male",
        "Dob": "2022-02-04",
        "Email": "[email protected]",
        "Tel": "8989092345",
        "Hobbies": [
            "Coding",
            "Gaming"
        ]
    }
]

I create the object to store using const formData = new FormData(form);.

Now when I am fetching the data to display it back into the form, I am using the following function –

const empIndex = employeeData[index];
    const form = document.getElementById("form");

    for(let i=0;i<form.length;i++){
        console.log(form.elements[i])
        console.log(empIndex[keys[i]]);
        
        form.elements[i].value = empIndex[keys[i]];
    }
    const gender = empIndex.Gender;
    const hobbies = empIndex.Hobbies;
    form.elements[0].value = empIndex.Name;

But the issue is, the radio buttons are treated as 2 different entities and not as 1, which is why I have to individually set the name as Name and what happens is shown below-
This is how the console looks after the logs

I need to know why does the HTML not deals the radio buttons as a group and a single entity, but rather makes it seperate entities, forcing me to input values with the loop into all the form elements, meanwhile I have created a group for a reason to be able to treat it as a single entity, just like an array. An array is a group of entities, but the HTML radio button group is not a group? Anyway to go about it?

console.log("i am inside the script");

var incorrect = true;

function uuidv4() {
  return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) =>
    (
      c ^
      (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))
    ).toString(16)
  );
}

function namechecker(name) {
  if (name == "" || name.length < 5 || name.length > 45) {
    document.getElementById("namehidden").style.display = "contents";
  } else {
    document.getElementById("namehidden").style.display = "none";
    incorrect = false;
  }
}

function dobChecker(dob) {
  if (!dob) {
    document.getElementById("dobhidden").style.display = "contents";
  } else {
    document.getElementById("dobhidden").style.display = "none";
    incorrect = false;
  }
}

function emailChecker(email) {
  const emailRegex =
    /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/;
  if (!(email && emailRegex.test(email))) {
    document.getElementById("emailhidden").style.display = "contents";
    incorrect = true;
  } else {
    document.getElementById("emailhidden").style.display = "none";
    incorrect = false;
  }
}

function phChecker(phone) {
  const phRegex = /^[6-9]d{9}$/;
  if (!phRegex.test(phone)) {
    console.log("Phone number is incorrect");
    document.getElementById("telhidden").style.display = "contents";
    incorrect = true;
  } else {
    document.getElementById("telhidden").style.display = "none";
    incorrect = false;
  }
}

function incorrectForm(name, dob, email, tel) {
  console.log(incorrect);
  namechecker(name);
  dobChecker(dob);
  emailChecker(email);
  phChecker(tel);
  if (!incorrect) return false;
  else return true;
}

function Init(form) {
  const formData = new FormData(form);
  const name = formData.get("name");
  const dob = formData.get("dob");
  const gender = formData.get("gender");
  const email = formData.get("email");
  const tel = formData.get("tel");
  const markedCheckbox = document.getElementsByName("hobbies");
  const hobbies = [];
  for (var checkbox of markedCheckbox) {
    if (checkbox.checked) {
      hobbies.push(checkbox.value);
    }
  }
  if (incorrectForm(name, dob, email, tel)) {
    console.log(
      "The form is incorrect. Kindly check and input correct entries."
    );
    alert("The Form is Incorrect. Kindly check the values and fill it correctly.")
  } else {
    return {
      U_Id: uuidv4(),
      Name: name,
      Gender: gender,
      Dob: dob,
      Email: email,
      Tel: tel,
      Hobbies: hobbies,
    };
  }
}

const but = document.getElementById("button");
console.log(but);
but.addEventListener("click", (event) => {
  event.preventDefault();
  console.log("i clicked the button");
  const f = document.getElementById("form");
  const object = Init(f);
  if (object) {
    if (!localStorage.getItem("employeeData")) {
      localStorage.setItem("employeeData", JSON.stringify([object]));
    } else {
      const existing = JSON.parse(localStorage.getItem("employeeData"));
      existing.push(object);
      localStorage.setItem("employeeData", JSON.stringify(existing));
    }
    console.log(localStorage.getItem("employeeData"));
  }
// calling another script from the button if the form is correct.
  if (!incorrect) {
    console.log("hi i am in basic!");

var tdStyle = "border:1px solid green;min-width:110px;";

const table = document.createElement("table");
table.setAttribute("style", "table-layout: fixed; width:max-content");

const tr = document.createElement("tr");
const employeeData = JSON.parse(localStorage.getItem("employeeData"));

console.log(employeeData);

if (employeeData){
const keys = Object.keys(employeeData[0]);

for (let i = 0; i < keys.length; i++) {
  const th = document.createElement("th");
  th.innerText = keys[i];
  th.setAttribute("style", tdStyle);
  tr.appendChild(th);
}

const action = document.createElement("th");
action.innerText = "Actions";
action.setAttribute("style", tdStyle);
tr.appendChild(action);
const thead = document.createElement("thead");
thead.appendChild(tr);
table.appendChild(thead);

const tbody = document.createElement("tbody");

function btnCreator(index) {
  const buttontd = document.createElement("td");
  const editBtn = document.createElement("button");
  editBtn.setAttribute("id" , "edit" + index);
  editBtn.innerText = "Edit";
  editBtn.setAttribute("style","margin-inline-end:10px");
  buttontd.setAttribute("style", tdStyle);
  const delBtn = document.createElement("button");
  delBtn.setAttribute("id", "delete" + index);
  delBtn.innerText = "Delete";
  editBtn.addEventListener("click", ()=>editListener(index));
  buttontd.appendChild(editBtn);
  buttontd.appendChild(delBtn);
  return buttontd;
}

function editListener(index){
    const empIndex = employeeData[index];
    const form = document.getElementById("form");

    for(let i=0;i<form.length;i++){
        console.log(form.elements[i])
        console.log(empIndex[keys[i]]);
        
        form.elements[i].value = empIndex[keys[i]];
    }
    const gender = empIndex.Gender;
    const hobbies = empIndex.Hobbies;
    form.elements[0].value = empIndex.Name;
    document.getElementById("chkbx1").checked = false;
    document.getElementById("chkbx2").checked = false;
    document.getElementById("chkbx3").checked = false;
    document.getElementById("rdbox1").checked = true;
    document.getElementById("rdbox2").checked = false;

    if (gender =="Female"){
        document.getElementById("rdbox1").checked = false;
        document.getElementById("rdbox2").checked = true;
    }

    hobbies.forEach((element)=>{
        switch (element){
            case "Gaming":
                document.getElementById("chkbx1").checked = true;
                break;
            case "Coding":
                document.getElementById("chkbx2").checked = true;
                break;
            case "Music":
                document.getElementById("chkbx3").checked = true;
                break;
            default:
            break;
                }
})
}

employeeData.forEach(function (item, index, arr) {
  const tr2 = document.createElement("tr");
  for (let i in item) {
    const td = document.createElement("td");
    td.innerText = item[i];
    td.setAttribute("style", "border:1px solid green; width:100%");
    tr2.appendChild(td);
  }
  tr2.appendChild(btnCreator(index));
  tbody.appendChild(tr2);
  table.appendChild(tbody);
});

const basicdiv = document.getElementsByClassName("basic")[0];

basicdiv.appendChild(table);}
else{

}
});
body{
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

.top-div{
    display: flex;
    margin-top: 200px;
    font-size: larger;
    font-weight: bold;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    width: 100%;
}

.mid-div{
  display: flex;
  flex-direction: column;
    background-color: #1282cc;
    color: black;
    border-top-left-radius: 4px;
    border-top-right-radius: 4px;
    width: 75%;
}

.bot-div{
  background-color: white;
  border: solid thin #1282cc;
  border-radius: 4px;
  padding-bottom: 2%;
}

form{
  width: 100%;
  display: flex;
  flex-direction: column;
}
.namelabel{
  margin-top: 10px;
}

.col-25 {
  float: left;
  text-align: right;
  width: 22%;
  margin-top: 6px;
}

.col-75 {
  float: right;
  width: 73%;
  margin-right: 2%;
}

.required{
  color: red;
}


.dob ,.tel,.email{
  width: 100%;
}


.vertical{
  margin: 0 2.5% 0 0;
}

#button{
  background-color: #1282cc;
  color: white;
  margin-top: 5%;
  padding: 1% 2%;
  border: #1282cc solid thin;
  border-radius: 4px ;
}

span.items{
  color:black;
  padding-left: 0;
}

div span{
    color: white;
    font-size: medium;
    font-weight: lighter;
    padding:15px;

}

* {
    box-sizing: border-box;
  }
  
  input[type=text] {
    width: 100%;
    height: 25px;
    border: 1px solid #ccc;
    margin: 32px 12px 12px 0;
    border-bottom-left-radius: 4px;
    border-bottom-right-radius: 4px;
  }

  input[type=radio]{
      margin: 23px 12px 12px 0;
  }

  input[type=date] {
    margin: 20px 12px 12px 0;
    border: 1px solid #ccc;
    height: 25px;
  }

  input[type=email] {
    margin: 23px 12px 12px 0;
    border: 1px solid #ccc;
    height: 25px;
  }

  input[type=tel]{
    margin: 23px 12px 12px 0;
    border: 1px solid #ccc;
    height: 25px;
  }
  
  label {
    padding: 12px 12px 12px 0;
    display: inline-block;
  }
  
.hidden{
  font-size: small;
  color: red;
  display: none;
}

.container {
    background-color: white;
    padding: 20px;
    border: blue 1px solid;
  }
  
  /* Clear floats after the columns */
  .row:after {
    content: "";
    display: table;
    clear: both;
  }

  @media screen and (max-width:840px) {
 
    .parent{
      display: flex;
      flex-direction: column;
    }

    .col-75{
      margin: 0;
      margin-left: 5%;
    }
    
    .col-25{
      width: 100%;
      margin: 0%;
      padding: 12px;
      text-align: left;
    }

    input[type=text] {
      margin: 10px 12px 12px 0;
    }

    input[type=email] {
      margin: 10px 12px 12px 0;
    }
  
    input[type=tel]{
      margin: 10px 12px 12px 0;
    }

    input[type=radio]{
      margin: 5px 5px 0 0;
  }

  .mf{
    display: flex;
  }
  }

  /* Adding styling for basic table */

  .basic{
    display: flex;
    flex-direction: row;
    width: 100%;
    overflow-x: auto;
  }
<!DOCTYPE html>
<html lang="en">

<head>
  <link rel="stylesheet" href="style.css" />
  <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>Employee Data</title>
  <script src="basic.js" defer></script>
</head>

<body>
  <div class="top-div">
    <h2>Employee</h2>
    <div class="mid-div">
      <span>Add Employee</span>
      <div class="bot-div">
        <form action="" id="form">
          <div class="parent">
            <div class="col-25">
              <label class="namelabel"> Name:</label>
            </div>
            <div class="col-75">
              <input name="name" type="text" maxlength="45" minlength="5" placeholder="Your Name" />
              <label class="hidden" id="namehidden">This field is required</label>
            </div>
          </div>
          <div class="parent">
            <div class="col-25">
              <label> Gender:</label>
            </div>
            <div class="col-75 mf">
              <div>
                <input type="radio" class="radio" name="gender" value="Male" id="rdbox1" checked /><span class="items">Male</span>
              </div>
              <div><input type="radio" class="radio" name="gender" value="Female" id="rdbox2"/><span class="items">Female</span>
              </div>
            </div>
          </div>
          <div class="parent">
            <div class="col-25">
              <label> Date of Birth:</label>
            </div>
            <div class="col-75">
              <input type="date" name="dob" class="dob" /><br>
              <label class="hidden visible" id="dobhidden">This field is required</label>
            </div>
          </div>
          <div class="parent">
            <div class="col-25">
              <label> Email:</label>
            </div>
            <div class="col-75">
              <input type="email" placeholder="Enter Email" name="email" class="email" />
              <br>
              <label class="hidden" id="emailhidden">This field is required</label>
            </div>
          </div>
          <div class="parent">
            <div class="col-25">
              <label> Phone:</label>
            </div>
            <div class="col-75">
              <input type="tel" placeholder="Enter phone" name="tel" class="tel" />
              <br>
              <label class="hidden" id="telhidden">This field is incorrect</label>
            </div>
          </div>
          <div class="parent">
            <div class="col-25">
              <label class="padding"> Hobbies:</label>
            </div>
            <div class="col-75 vertical" name="hobbies">
              <input class="chkbox" type="checkbox" name="hobbies" value="Gaming" id="chkbx1" /><span
                class="items">Gaming</span> <br>
              <input class="chkbox" type="checkbox" name="hobbies" value="Coding" id="chkbx2" /><span
                class="items">Coding</span> <br>
              <input class="chkbox" type="checkbox" name="hobbies" value="Music" id="chkbx3" /><span
                class="items">Music</span> <br>
            </div>
          </div>
          <div>
            <div class="col-75">
              <button type="submit" id="button">Submit</button>
            </div>
          </div>
        </form>
      </div>
    </div>
    <h2>Basic</h2>
    <div class="mid-div">
      <span>Add Employee</span>
      <div class="bot-div basic">
      </div>
    </div>
    <h2>Advanced</h2>
    <div class="mid-div">
      <span>Add Employee</span>
      <div class="bot-div">
        </div>
        </div>

  </div>
  </div>
</body>
<script src="script.js"></script>

</html>

Node Js pass the role as a string to the JWT verification function

the JWT verification function accepts the req, res and next as its params. I need to pass an additional string ‘Admin’ so that only admin users may access this API

My jwtVerification.js code:

module.exports = async function (req, res, next) { //I need to be able to add role to this call
    try {       
        const token = req.header("Authorization");

        if (!token) return res.status(401).send('Invalid access token.');

        const _token = token.substring(7, token.length);

        const decoded = jwt.verify(_token, process.env.JWT_PRIVATE_KEY)

        const user = await prisma.user.findFirst({ where: { id: decoded.id } });

        if (!user) return res.status(401).send('Invalid access token.');
     
        //I need to be able to read the role so that I can do the following verifications
        //if(!role) next();
        //else{
        //   if(user.role !== role || decode.role !== role) return res.status(403).send('Forbidden!')
        //   else next();
        //}
        next();

    } catch (error) {
        res.status(401).send(error.message);
    }
};

finally, the API call itself:
//use verifyJWT(‘Admin’) for example

router.post('/test', verifyJWT, async (req, res) => {
    res.send('hi');
})

How to make JS read the contents of a local text file

I know using JS to read the contents of a .txt is possible.

For example, I have a text file code.txt which contains

Abc
Ghi
123466
bored
idk

And I have index.js. I would like to use the contents of code.txt to create an array into index.js.

So, in that example, I would like an array like this to appear in index.js.

const entcode = [
  "Abc",
  "Ghi",
  "123466",
  "bored",
  "idk",
]

Is there a way to do that?

using flatmap to separate array with comma

I have the following array:

[
["Polymeric", "Vehicle Graphics (Basic)"],
["Cast", "Vehicle Graphics (Part Wrap), Vehicle Graphics (Full Wrap)"],
["Polymeric", "Vehicle Graphics (Part Wrap)"]
]

I need this:

[
["Polymeric", "Vehicle Graphics (Basic)"],
["Cast", "Vehicle Graphics (Part Wrap)"],
["Cast", "Vehicle Graphics (Full Wrap)"],
["Polymeric", "Vehicle Graphics (Part Wrap)"]
]

Here’s my code:

const source = [ 
  ["Polymeric", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, "Vehicle Graphics (Basic)"],
  ["Cast", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, "Vehicle Graphics (Part Wrap), Vehicle Graphics (Full Wrap)"],
  ["Polymeric", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, "Vehicle Graphics (Part Wrap)"]
];


source.flatMap(([key, value1, value2, value3, value4, value5, value6, value7, value8, value9, value10, value11, value12, value13, value14, value15, value16]) => { 

  const values = value16.split(', ') 

  var hjk = values.map(singleValue => [key, singleValue])
  console.log(hjk);
})

Here’s a jsfiddle of it working.

Is there a better way to do this? Putting value1, value2 etc seems silly.

How to trigger the Google Play login from React Native IAP

Is it possible to trigger the Google account sign-in dialogue from within a React Native app?

I have found while using IAPHub that you cannot even list products for sale if the user is not signed in on their Android device – because it seems to need to talk to the Play store with credentials.

Perhaps it’s an edge case, as most people would be always signed into their Google account if they use an Android device? But I felt like I wanted to be able to provide a nicer UX to show the login dialogue.

I’ve looked in the IAPHub docs and the repo docs the underlying https://github.com/dooboolab/react-native-iap but there doesn’t seem to be a direct interface to test if the user is logged in nor force a login. This makes me wonder if I’m looking in the wrong place.

I can see there’s a URL method like from https://stackoverflow.com/a/11753070/209288 but I was looking more for an in-app API.

Javascript – map is not a function

I’m having an odd issue. So I’m using fetch api to get some static data from an api endpoint to get some data. When I then try to map over the data it tells me map is not a function. So I’m making this in react. Also I haven’t used fetch too much so maybe I’m missing something easy.

Here is the fetchData code where I get the data no problem and then using setScanData(resData) for some state.

const fetchData = async () => {
  const res = await fetch(baseURL + apiAddOn);
  const resData = await res.json();
  setScanData(resData)
}

Here is how the resData comes back.

[
    {
        "teamName": "Team 1",
        "date": "2021-01-19",
        "tasksAWeek": 14
    },
    {
        "teamName": "Team 2",
        "date": "2021-01-19",
        "tasksAWeek": 21
    },
    {
        "teamName": "Team 3",
        "date": "2021-01-19",
        "tasksAWeek": 36
    }
]

And then here is how I try to map over the data and where is gives me the map is not a function error.

 {scanData.map((data) => {
        <div key={`${data.teamName}-${data.date}`}>
            <p>Team Name: {data.teamName}</p>
            <p>Date: {data.date}</p>
            <p>Scans a Week: {data.scansAWeek}</p>
            <p>Total Scans: {data.totalScans}</p>
        </div>
    })}

But ye so I’m not too sure where I’m going wrong with this. Any help would be useful.