How to correctly read and write any file in Jacascript?

I am building a form that allows a user to upload any file. Unfortunately, the file comes out distorted for non-simple file types such as .pdf (it works for simple .txt).

To test out that I am reading files correctly, I am using the following helper, as per this:

const makefile = (content: string) => {
  // Create element with <a> tag
  const link = document.createElement("a");

  // Create a blog object with the file content which you want to add to the file
  const file = new Blob([content], { type: "application/pdf" });

  // Add file content in the object URL
  link.href = URL.createObjectURL(file);

  // Add file name
  link.download = "sample.pdf";

  // Add click event to <a> tag to save file.
  link.click();
  URL.revokeObjectURL(link.href);
};

The helper creates an output file from the fed-in content.

I am reading and writing the file with:

  const onFinish = async (values: FormProps) => {
    const file = values.file?.originFileObj; // File type
    const reader = new FileReader();
    reader.addEventListener("load", (event) => {
      const binaryString = event.target?.result as string;
      makefile(binaryString);
    });

    if (!file) {
      return;
    }

    reader.readAsBinaryString(file);
  };

If everything works correctly, the downloaded sample.pdf should be identical to the input file read from the reader. However, that is not the case for more involved file types, such as .pdf.

The resulting file is corrupted and pdf readers can’t read it. It also comes out greater in size than the input file (for instance, 326KB output file size vs 222KB input file size).

I have tried different ways of reading the file, to no avail – all produce invalid output. What could be the issue?

How can I pass an ID name into jQuery as a parameter?

I have the following code which toggles the visibility of an item with a certain ID:

<div onClick="toggleViz()">Click this</div>

<div id="item1" style="display: none;">
   <p>Item 1       
</div>

<div id="item2" style="display: none;">
   <p>Item 2       
</div>

<script>
function toggleViz() {
    var x = document.getElementById("item1");
    if (x.style.display === "none") {
        x.style.display = "block";
    } else {
        x.style.display = "none";
    }
}
</script>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

I’d like to pass the ID name of the item whose visibility I want to toggle to the function as a parameter, so I don’t have to write a new function for every item.

When I try this:

<div onClick="toggleViz(item1)">Click this 1</div>
<div onClick="toggleViz(item2)">Click this 2</div>


<div id="item1" style="display: none;">
   <p>Item 1       
</div>

<div id="item2" style="display: none;">
   <p>Item 2       
</div>

<script>
function toggleViz(id_name) {
    var x = document.getElementById(id_name);
    if (x.style.display === "none") {
        x.style.display = "block";
    } else {
        x.style.display = "none";
    }
}
</script>

I get: Uncaught TypeError: Cannot read properties of null (reading 'style')

Animation of waves from numbers three.js

I’m trying to make waves consisting of numbers. I have a ready-made example consisting of dots.

It works, but I don’t understand how you can replace dots with numbers.

I use three.js

this.geometry = new THREE.PlaneBufferGeometry(4, 4, 128, 128);
    const material = new THREE.ShaderMaterial({
      uniforms: uniforms,
      linewidth: 100,
      vertexShader: this.vertexShader(),
      fragmentShader: this.fragmentShader()
    });

// const material = new THREE.MeshStandardMaterial();
this.mesh = new THREE.Points(this.geometry, material);
scene.add(this.mesh);`

Git Hub Repository

Validating and matching time interval string to number

I am trying to implement validator and converter that will accept string including time interval parts, check if it’s valid and convert to number of hours.

const validStrings = ["1day 5h", "1d 5hours", "1 days 5"]
// output should be 29

Currently I get all possible day and hours string units from Intl.DisplayNames object, depending on user locale and including “short”, “narrow” and “long” names (day, d, hour, hr…etc) and trying to match my string against those names splitting string into hours and days part and then extracting numeric parts.

The problem is that those units can be in plural form in different languages.

Is this something that requires my own custom implementation or there any known library that can handle this validation and conversion?

How to properly update interval from outside of the useEffect that it’s wrapped in?

I’m trying to use a state number to maintain the time of each interval but when I update the state value the interval remains the same. Here’s my codesandbox:

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

export default function App() {
  const [slideIndex, setSlideIndex] = useState<number>(1);
  const [intervalTime, setIntervalTime] = useState<number>(3000); // every 3 seconds

  useEffect(() => {
    const interval = setInterval(() => {
      setSlideIndex((slideIndex) => slideIndex + 1);
      console.log("but interval time is still: " + intervalTime);
    }, intervalTime); //  remains 3 seconds after clicking button
    return () => clearInterval(interval);
  }, []);

  const handleButtonClick = () => {
    setIntervalTime(1000);
    console.log("Interval time should be: " + intervalTime);
  };

  return (
    <div className="App">
      <h2>Counter: {slideIndex}</h2>
      <button onClick={() => handleButtonClick()}>
        shorten interval to 1 second
      </button>
    </div>
  );
}

How to keep the same position in the component after handle with another component?

I have a component that renders a list of cards with images. I have a button that handles showing another component and then going back to the list of cards with images.

The problem is that when I go back to the list of cards with images, whenever I go back to this screen it goes to the top of the page, showing from card number 1.

I would like it to continue showing the list of images where I left off. For example, if I was viewing card number 5, when I return to the screen, I would like to continue seeing card number 5.

Can you tell me how can I do this?

Here’s my code I put into codesandbox.io

enter image description here

import React, { useState } from "react";
import "./App.css";

export default function App() {
  const [renderMap, setRenderMap] = useState(false);
  return (
    <div className="main-world">
      {!renderMap ? (
        <div className="all-cards">
          {Array.from(Array(12), (_, index) => (
            <div key={`index_${index}`} className="all-cards-item">
              <div className="card-content">
                <div>
                  <img
                    src={`https://picsum.photos/500/300/?image=${index * 7}`}
                    alt=""
                  />
                </div>
                <h1>Card - {index + 1}</h1>
              </div>
            </div>
          ))}
        </div>
      ) : (
        <div>
          <h1>Map Area</h1>
        </div>
      )}
      <div className="content-button">
        <button
          onClick={() => {
            setRenderMap(!renderMap);
          }}
        >
          {!renderMap ? "Show Map" : "Show List"}
        </button>
      </div>
    </div>
  );
}

Thank you very much in advance.

Promise to set a variable, otherwise return

I am very new to promises and would 1) like to have this do what it needs to do, and 2) get feedback on the ‘more correct’ way to write it or any efficiencies that can be added.

The goal:
Check for the existence of an ID. If it exists, assign the node to a variable and then have a MutationObserver observe it for changes. If the ID does not exist, do not attempt to instantiate the observer.

The issue:
If the ID exists on the page, it will always take a bit to load. And I’m sure I’m not handling the ‘if it doesn’t exist’ portion correctly. And currently the variable is coming back false even when the ID eventually exists on the page.

The code:

document.addEventListener( 'DOMContentLoaded', () => {
    let control = false;


    function getControls() {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                    resolve([
                        document.getElementById('controls')
                    ]);
            }, 2000);
        });
    }

    getControls().then((node) => {
        control = node;
    });

console.log(layout_control); // currently false; Maybe there's a better way than setting an arbitrary timeout.

    if (!control) {
        return;
    } // Maybe this should be to do with 'reject.'

    new MutationObserver( function() {
            // Do some things when the controls change.

    } ).observe( control, {
            subtree: true,
            childList: true
        }
    );

} );

How to create subcollection with uid as collection name Firestore V9 (TS/React Native)

I have a collection at the root of my database, userCategories.

In my app, the user can add “categories”, the name of the category will be unique, and each category document looks like this:

{
  createdAt:Timestamp.now(),
  categoryName: userDefinedCategoryName,
  color:randomColorCode
}

I want the structure of this to be as follows:

root-
  |-userCollection
      |-uid1
      |-uid2
  |-userCategories
      |-uid1
          |-{createdAt:...,categoryName:"...",color:"..."}
           -{createdAt:...,categoryName:"...",color:"..."}
      |-uid2
          |-{createdAt:...,categoryName:"...",color:"..."}

I am currently using:

const categoryDocRef = doc(db, "userCategories", uid);
await setDoc(
  categoryDocRef, {
    createdAt:Timestamp.now(),
    categoryName:category,
    color:color
  }).then(() => {
    return {
      success: true,
      errorMessage:""
    };
  });

But this only allows me to create a single document within each uid, instead of multiple, as uid1 would have.

I am aware that I could do something like this:

const categoryDocRef = doc(db, "userCategories",uid);
const colRef = collection(categoryDocRef, "Anything Here")
await addDoc(
  colRef, {
    createdAt:Timestamp.now(),
    categoryName:category
    color:color
  }).then(() => {
    console.log(`User document for uid:${uid}`);
    return {
      success: true,
      errorMessage:""
    };
  });

But this creates a structure like this:

|-userCategories
    |-uid1
        |-anything here
            |-firebase generated id
                |-{createdAt:...,categoryName:"...",color:"..."}
                 -{createdAt:...,categoryName:"...",color:"..."}

I feel that the either the firebase generated id or the anything here part is unnecessary as I could use either categoryName or firebase generated id and it would avoid another layer of nesting.

Is there any way to achieve this?

JS: Can I call a function with same scope as caller or do macro-like behavior

I often have to check whether an object exists (or more commonly, whether the object structure exists deep enough) before storing something in it. I’m tired of doing things like this:

obj ? null : obj = {};
obj[key] = value;

Since that first line is so common, it would be good to modularize it (e.g. make it a function). I’d like to be able to do this:

ensureObj(obj);
obj[key] = value;

Better yet, overcast it because I more often need something like this:

ensureObj(obj, [k1, k2, k3]);
obj[k1][k2][k3] = value;

Of course you can write a function which takes obj and does obj ? null : obj = {}; but it will never do anything for you because you can’t call ensureObj(obj) if obj doesn’t exist (similar if the obj exists, but not the deeper path).

If I could call a function and ensure it uses the same scope as where it’s called from, that should do it — it seems to me that macros are the language feature that would be just the thing for this, but I see macros don’t exist in JS, though there are packages which simulate them for you. This doesn’t (yet) work for me because my understanding is you’re not actually writing JS, but something that gets compiled into JS — which I can’t insist the team move to without a much stronger reason.

So, without using something like sweet.js, is there a way I can modularize this test/prep process?

How can I make an email interactive/actionable (perhaps via Javascript) by a little icon click without having to goto another website?

I read this thread:
Is JavaScript supported in an email message?

But still the question remain relevant to me.

So how does really Yammer messages are actionable in Outlook?

There are thumbs up that’s possible, there’re sometimes voting that’s possible.
And from my memory (rather bad on this one) I think Gmail too allow that to a certain extent.

Are there any libraries that can be embedded in the Email HTML construction that support this kind of feature?

How to view frame source without using the button?

How to view frame source without using the button?

I want to make a custom chat app for me and my friends at school, and I found a good template here. The only problem is that I’m using Apps Script for this, meaning I don’t have advanced options. (I would use a different website hoster, but Apps Script is unblocked in our district.) I want to view the direct source of the app frame, but our district blocked the View page source and View frame source options. I know the trick of using view-source: in a url like view-source:https://stackoverflow.com/, but I was wondering if there was a way to get the frame source using a URL tag? I tried importing the code to Apps Script using the provided boxes and referencing CSS files on a GitHub repository, and everything was working well until I realized that jQuery wouldn’t import.

Using Whatsapp Business to auto-reply when a customer enters the chat

I’m using VueJS.
I have created a Whatsapp business account, and I created a button in my site – whenever the user clicks on it, a new tab will be opened and he will be in a chat with my Whatsapp Business account.
I was able to do it, but the thing I couldn’t do – is that whenever the user just enters the chat (without sending a message), I want my Whatsapp business to automatically send him “Hello, how can I help you?”.

<template>
  <button @click="openWhatsApp">Connect on WhatsApp</button>
</template>

<script>
export default {
  methods: {
    openWhatsApp() {
      const companyPhoneNumber = "999999999";
      const message = encodeURIComponent("Hello, how can I help you?");
      const url = `https://wa.me/${companyPhoneNumber}`;

      window.open(url, "_blank");
    },
  },
};
</script>

I do not know how to add a score counter to my quiz

I am currently working on a sonic themed trivia quiz, everything is currently going swimmingly except for one thing…I can’t figure out how to make a score counter, and I can’t seem to find a tut on how to make one, I would rly appreciate it if someone could shed some light on my situation…plz?

here is my code curently:

document.querySelector(".wrong-answer").addEventListener('click', incorrect)
document.querySelector(".wrong-answer-two").addEventListener('click', incorrect)
document.querySelector(".right-answer").addEventListener('click', correct)
document.querySelector(".wrong-answer-three").addEventListener('click', incorrect)


function incorrect() {
    alert('WRONG ANSWER')
}

function correct() {
    alert('GREAT JOB!')
}


AmCharts 4 Map Chart label size inconcistent

I’ve a situation with a dashboard page where I’m using AmCharts 4 Map Chart in two different tabs.

When I render each of them by the first time, both get labels with the size I’ve defined, but when I open any of them for the second time and on, the labels get giant and makes the map unreadable.

I can’t share the customer code, but I tried to provide a code pen with a similar behavior here

/**
 * ---------------------------------------
 * This demo was created using amCharts 4.
 *
 * For more information visit:
 * https://www.amcharts.com/
 *
 * Documentation is available at:
 * https://www.amcharts.com/docs/v4/
 * ---------------------------------------
 */

mapData = [{
    id: 'US-AL',
    value: 40223504
  },
  {
    id: 'US-AK',
    value: 30345487
  },
  {
    id: 'US-AZ',
    value: 22359251
  },
  {
    id: 'US-AR',
    value: 20448194
  },
  {
    id: 'US-CA',
    value: 13092796
  },
  {
    id: 'US-CZ',
    value: 12807072
  },
  {
    id: 'US-CO',
    value: 11878330
  },
  {
    id: 'US-CT',
    value: 11019186
  },
  {
    id: 'US-DE',
    value: 10710558
  },
  {
    id: 'US-DC',
    value: 10135438
  },
  {
    id: 'US-FL',
    value: 9438124
  },
  {
    id: 'US-GA',
    value: 8820504
  },
  {
    id: 'US-GU',
    value: 7999503
  },
  {
    id: 'US-HI',
    value: 7379346
  },
  {
    id: 'US-ID',
    value: 7174604
  },
  {
    id: 'US-IL',
    value: 7080262
  },
  {
    id: 'US-IN',
    value: 6876047
  },
  {
    id: 'US-IA',
    value: 6298325
  },
  {
    id: 'US-KS',
    value: 6204710
  },
  {
    id: 'US-KY',
    value: 5997070
  },
  {
    id: 'US-LA',
    value: 5955737
  },
  {
    id: 'US-ME',
    value: 5827265
  },
  {
    id: 'US-MD',
    value: 5266343
  },
  {
    id: 'US-MA',
    value: 5097641
  },
  {
    id: 'US-MI',
    value: 4695071
  },
  {
    id: 'US-MN',
    value: 4555777
  },
  {
    id: 'US-MS',
    value: 4359110
  },
  {
    id: 'US-MO',
    value: 4021753
  },
  {
    id: 'US-MT',
    value: 3615499
  },
  {
    id: 'US-NE',
    value: 3423935
  },
  {
    id: 'US-NV',
    value: 3233572
  },
  {
    id: 'US-NH',
    value: 3225832
  },
  {
    id: 'US-NJ',
    value: 3040207
  },
  {
    id: 'US-NM',
    value: 2963308
  },
  {
    id: 'US-NY',
    value: 2959473
  },
  {
    id: 'US-NC',
    value: 2135024
  },
  {
    id: 'US-ND',
    value: 2002052
  },
  {
    id: 'US-OH',
    value: 1920562
  },
  {
    id: 'US-OK',
    value: 1775932
  },
  {
    id: 'US-OR',
    value: 1483762
  },
  {
    id: 'US-PA',
    value: 1395847
  },
  {
    id: 'US-PR',
    value: 1372559
  },
  {
    id: 'US-RI',
    value: 1112668
  },
  {
    id: 'US-SC',
    value: 1110822
  },
  {
    id: 'US-SD',
    value: 1017551
  },
  {
    id: 'US-TN',
    value: 908414
  },
  {
    id: 'US-TX',
    value: 811044
  },
  {
    id: 'US-UT',
    value: 740339
  },
  {
    id: 'US-VT',
    value: 648279
  },
  {
    id: 'US-VI',
    value: 580817
  },
  {
    id: 'US-VA',
    value: 740339
  },
  {
    id: 'US-WA',
    value: 740339
  },
  {
    id: 'US-WV',
    value: 740339
  },
  {
    id: 'US-WI',
    value: 740339
  },
  {
    id: 'US-WY',
    value: 740339
  }
];


//MAP 1
// Create map instance
var chart = am4core.create("chartdiv1", am4maps.MapChart);

// Set map definition
chart.geodata = am4geodata_usaHigh;

// Set projection
chart.projection = new am4maps.projections.AlbersUsa();

// Create map polygon series
var polygonSeries = chart.series.push(new am4maps.MapPolygonSeries());

// Make map load polygon (like country names) data from GeoJSON
polygonSeries.useGeodata = true;
polygonSeries.calculateVisualCenter = true;

// Add some data
polygonSeries.data = mapData;

// Configure series
var polygonTemplate = polygonSeries.mapPolygons.template;
console.log('pt', polygonTemplate);
polygonTemplate.tooltipText = "{name} : {value}";
polygonTemplate.fill = am4core.color("#74B266");

// Create hover state and set alternative fill color
var hs = polygonTemplate.states.create("hover");
hs.properties.fill = am4core.color("#367B25");

var labelSeries = chart.series.push(new am4maps.MapImageSeries());
var labelTemplate = labelSeries.mapImages.template.createChild(am4core.Label);
labelTemplate.horizontalCenter = 'middle';
labelTemplate.verticalCenter = 'middle';
labelTemplate.fontSize = 10;
labelTemplate.interactionsEnabled = false;
labelTemplate.nonScaling = false;

polygonSeries.events.on('inited', () => {
  for (var i = 0; i < mapData.length; i++) {
    const itemId = mapData[i]['id'].toString();
    var polygon = polygonSeries.getPolygonById(itemId);
    if (polygon) {
      var label = labelSeries.mapImages.create();
      var state = itemId.split('-').pop();
      label.longitude = polygon.visualLongitude;
      label.latitude = polygon.visualLatitude;
      label.children.getIndex(0).text = `${mapData[i].value} n ${state}`;
    }
  }
})
// MAP 1 END

//MAP 2
// create second map instance
var chart2 = am4core.create('chartdiv2', am4maps.MapChart);
chart2.geodata = am4geodata_usaHigh;

// Set projection
chart2.projection = new am4maps.projections.AlbersUsa();

// Create map polygon series
var polygonSeries2 = chart2.series.push(new am4maps.MapPolygonSeries());

// Make map load polygon (like country names) data from GeoJSON
polygonSeries2.useGeodata = true;
polygonSeries2.calculateVisualCenter = true;

// Add some data
polygonSeries2.data = mapData;

// Configure series
var polygonTemplate2 = polygonSeries2.mapPolygons.template;
console.log('pt', polygonTemplate2);
polygonTemplate2.tooltipText = "{name} : {value}";
polygonTemplate2.fill = am4core.color("#6495ED");

// Create hover state and set alternative fill color
var hs = polygonTemplate2.states.create("hover");
hs.properties.fill = am4core.color("#0000FF");

var labelSeries2 = chart2.series.push(new am4maps.MapImageSeries());
var labelTemplate2 = labelSeries2.mapImages.template.createChild(am4core.Label);
labelTemplate2.horizontalCenter = 'middle';
labelTemplate2.verticalCenter = 'middle';
labelTemplate2.fontSize = 10;
labelTemplate2.interactionsEnabled = false;
labelTemplate2.nonScaling = false;

polygonSeries2.events.on('inited', () => {
  for (var i = 0; i < mapData.length; i++) {
    const itemId = mapData[i]['id'].toString();
    var polygon = polygonSeries2.getPolygonById(itemId);
    if (polygon) {
      var label = labelSeries2.mapImages.create();
      var state = itemId.split('-').pop();
      label.longitude = polygon.visualLongitude;
      label.latitude = polygon.visualLatitude;
      label.children.getIndex(0).text = `${mapData[i].value} n ${state}`;
    }
  }
})

//MAP 2 END
:root {
  --theme-yellow: #FEE715FF;
  --theme-black: #101820FF;
  --theme-gray: #8892B0;
}

body {
  background-color: var(--theme-black);
}


/* SECTION VERTICAL TABS */

#experienceTab.nav-pills .nav-link.active {
  color: var(--theme-yellow) !important;
  background-color: transparent;
  border-radius: 0px;
  border-left: 3px solid var(--theme-yellow);
}

#experienceTab.nav-pills .nav-link {
  border-radius: 0px;
  border-left: 2px solid var(--theme-gray);
}

.date-range {
  letter-spacing: 0.01em;
  color: var(--theme-gray);
}


/* STUB  LINKS */

a {
  color: var(--theme-gray);
  transition: 0.3s eas-in-out;
}

a:hover {
  color: var(--theme-yellow);
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>CodePen - amcharts 4 scale label</title>
  <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css'>
  <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.13.0/css/mdb.min.css'>
  <link rel="stylesheet" href="./style.css">

</head>

<body>
  <!-- partial:index.partial.html -->
  <div class="row p-5">
    <div class="col-md-2 mb-3">
      <ul class="nav nav-pills flex-column" id="experienceTab" role="tablist">
        <li class="nav-item">
          <a class="nav-link active" id="home-tab" data-toggle="tab" href="#snit" role="tab" aria-controls="home" aria-selected="true">Map 1</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" id="profile-tab" data-toggle="tab" href="#devs" role="tab" aria-controls="profile" aria-selected="false">Map 2</a>
        </li>
      </ul>
    </div>
    <!-- /.col-md-4 -->
    <div class="col-md-10">
      <div class="tab-content" id="experienceTabContent">

        <div class="tab-pane fade show active text-left text-light" id="snit" role="tabpanel" aria-labelledby="home-tab">
          <h3>Map 1</h3>
          <div class='chartdiv1'></div>
        </div>

        <div class="tab-pane fade text-left text-light" id="devs" role="tabpanel" aria-labelledby="profile-tab">
          <h3>Map 2</h3>
          <div class='chartdiv2'></div>
        </div>
      </div>
      <!--tab content end-->
    </div>
    <!-- col-md-8 end -->
  </div>
  <!-- partial -->
  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js'></script>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/js/bootstrap.min.js'></script>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.13.0/js/mdb.min.js'></script>
  <script src='https://cdn.amcharts.com/lib/4/core.js'></script>
  <script src='https://cdn.amcharts.com/lib/4/maps.js'></script>
  <script src='https://cdn.amcharts.com/lib/4/geodata/usaHigh.js'></script>
  <script src="./script.js"></script>

</body>

</html>

Any help would be really appreciated.