HTML / JS typing animation not working in all mobile browsers

i have a typing animation on my website but i got the feedback, that this animation is not working on some mobile devices (with eg. Chrome) – not starting. There are no problems at desktop browsers. What could be the problem in the code?

HTML Code

<div class="text_typing">
<span class="animation_text_word"></span>
</div>

JS Code

function animate_text(){
    
    "use strict";
    
    var animateSpan         = jQuery('.animation_text_word');
    
        animateSpan.typed({
            strings: ["Text1", "Text2", "Text3", "Text4"],
            loop: true,
            startDelay: 1e3,
            backDelay: 2e3
        });
}

What can i search for to filter out the problem?

Promise.catch() not catching errors from promise

I’m trying to check a number of conditions, and if one of them is true I want to proceed to a certain callback function. Otherwise, I want to proceed to a different callback function. Some pseudocode might look like:

if (condition_1 OR condition_2 OR condition_3) {
    on_satisfied()
} else {
    on_unsatisfied()
}

However, checking each of these conditions takes a while (for example, it may require a database query), so I want to check them asynchronously. I also know that if any one of them returns TRUE, I have already satisfied my condition and thus want to stop execution and forget about the remaining conditions. In hopes of doing that, I wanted to use the “dirty trick” described here in the first response: throwing an error that will be handled within a parent function (which is inside a promise here)

// the function we call if at least one condition is satisfied
function on_satisfied() {
    console.log("At least one condition satisfied")
}

// the function we call if no conditions are satisfied
function on_unsatisfied() {
    console.log("No conditions satisfied")
}

// a sample condition-checking function
async function check_lessthan_5(to_check, callback_if_not) {
    // using a timeout to simulate "slow" checking of conditions;
    // the slow checking could be a result of e.g. database queries
    await new Promise(r => setTimeout(r, 2000));
    if (to_check < 5) {
        // throw this error in hopes of terminating parent function,
        // because it is sufficient for one condition to be met 
        // in order for the whole OR-joined expression to be true (we want to stop execution of the parent function)
        throw Error("value < 5")
    }
    return false
}

const all_cond_checker = new Promise((resolve, reject) => {
    // store all the resulting promises, 
    // so when they all resolve we know that no conditions were satisfied
    var conditions_list = []
    // check all the conditions. In this case, we want to see if any of these numbers is >= 5
    for (var i=0; i < 10; ++i) {
        // push a resulting promise into the list, we can check later that it resolves
        // if the condition is met, terminate this function by propagating error up
        conditions_list.push(check_lessthan_5(i)).catch((error) => {resolve()})
    }
    // once all the promises return, us getting here implies no errors were thrown 
    // which implies no conditions satisfied
    Promise.all(conditions_list).then(reject)
});

The problem is that it seems like the .catch() inside the promise does not catch the error! Running the code, I get the following:

$ node async_test.js
No conditions satisfied
/home/daniel/Signoff-again/node-experiments/async_test.js:20
            throw Error("value >= 5")
            ^

Error: value < 5
    at Timeout._onTimeout (/home/daniel/Signoff-again/node-experiments/async_test.js:20:19)
    at listOnTimeout (node:internal/timers:557:17)
    at processTimers (node:internal/timers:500:7)

My interpretation of these results is that, for some reason, the .catch() is totally skipped, the error is unhandled, the for-loop is broken, then the Promise.all() is executed (because all 5 of the Promises in conditions_list have been resolved) and so the on_unsatisfied function is called. Instead, what I would want/expect is for the on_satisfied function to be called as soon as the first check_lessthan_5 returns.

So the question: why is it happening that the catch() seems not to work here? Also, is there a better way of doing this?

Thanks in advance.

I expect that as soon as the first condition is satisfied, the returned error is caught by the .catch() in all_cond_checker and then on_satisfied is called. I do not expect the error to propagate all the way “out” and be reported in the console.

The expected console output is:

$ node async_test.js
At least one condition satisfied

How can I dynamically display some contents of an Electron BrowserWindow in a web browser?

Inside my main BrowserWindow in my Electron app, there is a . I want to display the contents of this element in an actual web browser window on localhost. The text in the web browser needs to continuously update as the user types more text into the . I am trying to use an HTTP server + WebSocket to achieve this but I don’t understand how to display my Electron HTML page in the browser.

Whenever the user types a new word, I send the word to the main process, which then sends it to the secondary renderer process via this handler:


ipcMain.on('send-chunk', async (_event, data) => {
    console.log('data from main renderer:', data)
    mainWindow.webContents.send('receive-chunk', data)
  })

The secondary renderer process looks like this:


const { ipcRenderer } = require('electron')
const WebSocket = require('ws')

const webReaderDisplay = document.getElementById('web-reader-display')
const webReaderContents = []

const ws = new WebSocket('ws://localhost:8080')

ws.onopen = function (event) {
  console.log('WebSocket connection opened:', event)
}

ws.onmessage = function (event) {
  console.log('renderer received: %s', event.data)
  webReaderContents.push(event.data)
  webReaderDisplay.textContent = webReaderContents.join(' ')
}

ws.onerror = function (event) {
  console.error('WebSocket error observed:', event)
}

ws.onclose = function (event) {
  console.log('WebSocket connection closed:', event)
}

ipcRenderer.on('receive-chunk', (_event, data) => {
  ws.send(data)
})

Here is the server code:


const Server = require('http')
const { WebSocketServer } = require('ws')

const server = Server.createServer((req, res) => {
  res.writeHead(200)
  res.end('hello world')
})

const wss = new WebSocketServer({ server })

wss.on('connection', ws => {
  console.log('Client connected')

  ws.on('message', message => {
    console.log('received: %s', message)
  })

  ws.on('close', () => {
    console.log('Client disconnected')
  })
})

server.listen(8080)

And finally here is the HTML file:


<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <link href="../dist/output.css" rel="stylesheet" />
  </head>
  <body>
    <header class="text-center text-system-platinum bg-system-gray-dark">
      <h3>Live Transcript</h3>
    </header>
    <section class="bg-system-platinum">
      <div class="border-system-gray-dark indent-4">
        <p class="text-system-gray-dark" id="web-reader-display">
          Text will appear here
        </p>
      </div>
    </section>
    <script src="webReaderRenderer.js"></script>
  </body>
</html>

How can I make a popup about blank window with an embedded page in it?

I have two sets of code here,

<button onclick="NewTab()">Open</button>

    <script>
        function NewTab() { 
            window.open("random website",
                    "", "width=1150, height=611",'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no');
       }
    </script>

This code will obviously open the window as a popup, pretty simple.
Heres the other set of code,

<button onclick="openGame()">Open</button>
<script>
function openGame() {
var win = window.open()
var url = "random website 2","", "width=1000, height=565",'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no'
var iframe = win.document.createElement('iframe')
iframe.style.width = "100%";
iframe.style.height = "100%";
iframe.style.border = "none";
iframe.src = url
win.document.body.appendChild(iframe)
}
</script>

This code will open the window, but embed it in an about:blank.

Im not really sure how to approach this code, and make them work together so that when you click a button, it will open the window, as a popup like the first code does, but embedded into an about:blank.
Is this even possible? if it is, what am I not doing here?

Issue with javascript with use passive listeners

as many topics has with this issue i can’t figure out how to manage it correct in two .js files
For the one file i will post what i do and it doesnt show any errors anymore but i’m not sure is it correct.
Main error that i receive is:
Does not use passive listeners to improve scrolling performance
Consider marking your touch and wheel event listeners as passive to improve your page’s scroll performance.

Select2.js and Jquery.js.
https://pastebin.com/61yjrdri - Select2.js https://pastebin.com/VNCwLJLN - Jquery.js

so what i try in Select2.js was like this:

this.$element[0].addEventListener(
        'DOMAttrModified',
        self._syncA, **{passive: true}**
        false
      );

It removes me the message error, but i’m not sure is the correct way to fix it.

Cannot import MongoClient from the mongodb Module

i am trying to import the MongoClient object from the mongodb module after i installed it via the node package manager using the following command:

npm i mongodb

I am using the following line of code to import the object from the module:

import { MongoClient } from 'mongodb';

After opening the browser to check if there is any errors i get the following error:

Uncaught TypeError: Failed to resolve module specifier “mongodb”. Relative references must start with either “/”, “./”, or “../”.

How can i solve this ? I searched and i didnt get any answer regarding this error. I am trying to query the database i am creating locally using MongoDB, i also tried to specify the path on the import, but the result is the same.

Thank you !

Why moving to TypeScript from Javascript?

This might sound like a stupid question, but I’m genuinely trying to grasp it better. And if Stack Overflow isn’t the best place for this kind of question, please suggest a more suitable platform in the comments, and I’ll move it there.

So, TypeScript’s primary advantage is its emphasis on type safety, as the name suggests. The aim is to enhance the safety of working with objects of different types.

But is it truly worth it?

It does have its benefits, but it comes with a trade-off. You’re committed to explicitly maintaining types throughout the entire codebase, which, while not bad, does require extra time for upkeep.

Personally, I transitioned from Java to Javascript. And I quickly started to appreciate the freedom it offers compared to Java’s strictness. Looking back, Java’s rigidity now feels burdensome.

TypeScript, in a way, feels like a step back. Working extensively with Javascript over the years, I encountered type-related issues only a few times, and they were usually easy to fix.

At the moment it feels like TypeScript is more like an entry-level-friendly language, while for as long as you know what you do, Javascript remains an excellent choice.

However, I sense it’s not that straightforward. Has anyone dedicated time to dive deeper into this topic?

react-virtualized forceUpdateGrid method does not cause re-rendering with new data

I use react-virtualized library,in particular , the ‘List’ component. ContactsList the component in which the list of contacts is rendered. ContactsList has the ability to filter contacts.There is a problem when I try to filter the list, namely the List component ceases to filter any data. Although filtered data is logged in the ContactsList component, that is, the filteredContacts array is not empty. In this regard, the question is, how can I get an updated list of content. In the official documentation for the library react-virtualized describes forceUpdateGrid method, but in my case, it didn’t work.Perhaps someone knows how to make the List component display updated data.

    export const ContactsList = ({ headerRightSlot }: ListOfContactsProps) => {
    
    React.useEffect(() => {phoneNumbersListRef.current?.forceUpdateGrid()}[filteredContacts.length])
    
    const [filteredContacts, setFilteredContacts] = React.useState<ContactType[]>([]) 
    
    const phoneNumbersListRef = React.useRef<List>(null)
            
    const renderRow = ({ index, key, style, isScrolling }: RowRenderProps) => {

      const contact = filteredContacts[index]
      const margin = 5
      let position = 0
      if (selectedContactIndex !== undefined && index > selectedContactIndex) {
          position = index * (rowHeight + margin)}
 
         else {
              position = index * (rowHeight + margin)
            }
      const newStyle = { ...style, top: position }
            
        return (
            <div key={key} style={newStyle}>
            {contact && (<Contact
                            key={key}
                            contact={contact}
                            handleSubTitleClick={(state: unknown) => {
                              if (
                                typeof state === 'object' &&
                                state !== null &&
                                'isOpened' in state
                              ) {
                                if (state.isOpened) {
                                  setSelectContactIndex(undefined)
                                } else {
                                  setSelectContactIndex(index)
                                }
                              } else if (
                                typeof state === 'object' &&
                                state !== null &&
                                'offset' in state
                              ) {
                                if (typeof state.offset === 'number') {
                                  setOffset(state.offset)
                                }
                              }
                            }}
                            contentSlot={
                              <PhoneNumbersList phones={contact?.phones} contact={contact} />
                            }
                            rightSlot={
                              <>
                                <AddToFavorite contactId={contact?.id} />
                                <CallToContact contact={contact} />
                              </>
                            }
                          />
                        )}
                      </div>
}
          
return (
        <Panel className={panelClasses}>
          <Panel.Header
            withBackButton
            handleClickBackButton={() => send('back')}
            title={'Contact List'}
            rightSlot={headerRightSlot}
          />
    
          <Panel.Body className={listOfContactsClasses}>
            {Array.isArray(filteredContacts) && filteredContacts.length > 0 ? (
              <div style={{ height: '100%' }}>
                <AutoSizer>
                  {({ height, width }) => {
                    return (
                      <List
                        ref={phoneNumbersListRef}
                        width={width}
                        height={height}
                        rowHeight={rowHeight}
                        rowCount={rowCount}
                        rowRenderer={renderRow}
                        overscanRowCount={10}
                        style={{ paddingRight: 8 }}
                      />
                    )
                  }}
                </AutoSizer>
              </div>
            ) : (
             
              <Typography
                id={'title'}
                className={styles['search-list-no-results-title']}
                as={'caption'}
                decoration={'none'}
                tag={5}
                weight={1}>
                There are no suitable results
              </Typography>
            )}
          </Panel.Body>
        </Panel>
      )
                }

Missing inputs error on broadcast hex in litecoin testnet

I’m trying to create an LTC wallet in Node.js, but I keep getting the error ‘Missing inputs’ when I try to broadcast.

I’m trying to create a Litecoin wallet in Node.js using the ‘litecoinjs’ library. I can create the hex, but when I try to broadcast it on the ‘https://tltc.bitaps.com/broadcast’ site, it returns an error ‘Missing inputs.’ The UTXO I’m passing is as follows:

[
  {
    txid: '40b77ce9e96f0e85e4b026c1624c53b45a64c8a813df9a08ccde78c7a1b1d011',
    index: 1,
    amount: 95426081,
    script: 'a9141f652a42c312a2c4aee837672ce5c84a0b0455a087'
  }
]

And the code I’m using is this:

async function newTxExample(wallet, addressToSend, amount) {
    try {
        amount = await toLitoshi(amount);
        let utxo = await getUX(wallet.address);
        utxo = await converterUTXO(utxo);
        const transaction = await litecoinjs.newTransaction({
            network: 'testnet',
            wif: wallet.wif,
            utxo: utxo,
            output: [{
                address: addressToSend,
                amount: amount
            }],
            fee: 1000,
        });
    } catch (error) {
        console.error(`ERROR: ${error}`);
    }
}

.then() doesnt seem to wait until the previous then() Method is done

In my current application you can define some trainings for your sport club. Those trainings are saved into a Database and when you open the overview, you are able to see a list of all the trainings within the database.

Depending on the role of the user who is currently logged in(ADMIN or TRAINER) you can either edit/delete those trainings or not. Admin can, Trainer cannot. If you are not an admin, the buttons edit/delete are disabled.

The overview is rendered with this function:

function renderOverview() {
    clearDynamic();
    let template = document.getElementById("training-overview-TPL");
    let tClone = template.content.cloneNode(true);
    let wrapper = tClone.querySelector(".trainings-wrapper");
    dynamic.append(wrapper);
    
    let req = {
        task: "fetch_all_trainings",
    };
    fetch(API_TRAININGS, {
        headers: {"Content-Type":"application/json"},
        method: "post",
        body: JSON.stringify(req),
    })
    .then(res => res.json())
    .then(async data => {
        if(data.allTrainings.length > 0) {
            data.allTrainings.forEach(async training => {
                let row = await renderTrainingRow(training);
                wrapper.append(row);
            });
        }
    })
    .then(() => {
        fetch(API_LOGGED_USER)
        .then(res => res.json())
        .then(user => {
            if(user.role !== "ADMIN") {
                console.log("Logged User is NOT AN Admin");
                let BTNS_edit = document.querySelectorAll(".BTN_edit_training");
                let BTNS_delete = document.querySelectorAll(".BTN_delete_training");
                console.log(BTNS_edit);
                console.log(BTNS_delete);

                setTimeout(() => {
                    BTNS_edit.forEach(e => {
                        e.disabled = true;
                    });
                    BTNS_delete.forEach(e => {
                        e.disabled = true;
                    });
                }, 200);
            }
        });
    });
}

wihtin that function there is another function “renderTrainingRow” invoked for the number of trainings that are fetched from the backend. renderTrainingRow creates a single Row that includes the edit/delete-buttons:

async function renderTrainingRow(training) {
    let template = document.getElementById("training-row-TPL");
    let tClone = template.content.cloneNode(true);
    let name = tClone.querySelector(".name-cell");
    name.innerText = `${training.trainingname}`;


    let BTN_edit = tClone.querySelector(".BTN_edit_training");
    BTN_edit.addEventListener("click", () => {
        renderEditTrainingForm(training.trainingid);
    });
    let BTN_delete = tClone.querySelector(".BTN_delete_training");
    BTN_delete.addEventListener("click", () => {
        deleteTraining(training.trainingid);
    });
        // parse the fetched Group Array from JSON to JS Array:
        let trainingGroupsAsIDsInArray = JSON.parse(training.traininggroups);
        let req = {
            task: "fetch_all_groups",
        };
        // get all the existing groups:
        let groupResponse =
        await fetch(API_GROUPS, {
            headers: {"Content-Type":"application/json"},
            method: "post",
            body: JSON.stringify(req),
        });
        let res = await groupResponse.json();
        let allGroups = res.allGroups;

        // which one of all groups does the user belong to:
        let groupsOfTraining = allGroups.filter(function(curr) {
            return trainingGroupsAsIDsInArray.includes(curr.groupid);
        });

        let group = tClone.querySelector(".group-cell");
        let groupcelltext = "<strong class='me-1'>Gruppen: </strong>";
        if(groupsOfTraining.length > 0)
        {
            groupsOfTraining.forEach(grp => {
                groupcelltext += ` <span class='badge bg-tertiary me-1'>${grp.groupname}</span> `;
            })
        }
        else {
            groupcelltext += " - ";
        }
        group.innerHTML = groupcelltext;

    return tClone;
}

As you can see in the function renderOverview, within the last then() – Method of the then() – Chain that starts after the fetch of all Trainings, thats the part where the programm decides if the buttons are clickable or not(depending of the role of the fetched logged user)

It all works very good, but here is the problem: Sometimes the last trainings are not affected by the disabling of the buttons. As you can see in the following picture, the last entry is not affected. Sometimes its only the last entry, but sometimes the last 2 entries are affected. Most of the times every entry is affected but i dont want to make it dependant of luck. If i had to estimate, my gut tells me that 70% of the times every entry is affected, 15% the last one isnt and 15% the last 2 entries are not affected. But look for yourselfs how it looks:

Last Edit-Button is not disabled

Looking at the way it behaves i am pretty sure it has sth to do with the async nature of the program, but i cannot find out why, because i assumed that every then() methods waits, till the previous one has finished. I even added that setTimeout to “give javascript some time” getting every entry, but it also didnt work.

As you can see in the DOM i console.log all the affected buttons and the console only shows me the ones that got affected, not just every button that was rendered in the then()-Method before:

Not affected

Whats the nature of my problem and how do i solve it?

Implementing server-side caching middleware in tRPC 10

I’m working on a Next.js project and looking to implement in-memory caching for tRPC results, with each tRPC procedure being able to opt-in with a custom TTL. I think tRPC’s middleware would be suitable for this purpose. Unfortunately, the current tRPC middleware documentation doesn’t seem to cover this specific scenario.

How can a server-side caching middleware in tRPC 10 be implemented?

How To Correctly Handle Success/Error with True-Myth

I’ve been trying out true-myth to wrap http responses, but I think I’m missing something because I am ending up with the inverted pyramid for subsequent requests. Something like:

const authRes = await verifyAuth(req)
if (authRes.isOk) {
  const id = authRes.value.id
  const roleRes = await getRole(id)
  if (roleRes.isOk) {
    const accessRes = await canAccess(roleRes.value, req.docId)
      if (accessRes.isOk) {
        // Etc
      }
    }
  }
}

This is a contrived example, but how can I avoid this pyramid of doom?

Also, if any of these error, the error propery isn’t clear to typescript without an additional isErr check, ie

const authRes = await verifyAuth(req)
if (authRes.isOk) {
  return true
} else {
  // ts error with or without else
  return { 
    status: 401,
    // red typescript squiggly under error saying it isn’t a property on authRes
    error: authRes.error 
  }
}
if (authRes.isErr) {
  return { 
   status: 401,
   // must wrap with isErr check before accessing error property, which adds two lines for every http request I want to have a separate error for
   error: authRes.error 
  }
}

This isn’t real code so I’m just talking about concepts here. How can I avoid these two scenarios that seem like they’ll really inflate the size? Anyone used this library and have an idea about something obvious I’m missing or if I’m just misusing true-myth somehow?

Timezone conversion script slowing down refresh of Jekyll site

I am building a site with Jekyll. On a page, I wish to convert dates from UTC to the local timezone, so I am calling a JS script in the head of _layout/page.html

<head>
    <!-- Load script to convert UTC time to local time -->
    <script defer type="text/javascript" src="/assets/js/get_local_time.js"></script>
</head>

where the get_local_time.js script is

// JavaScript code to convert UTC time of seminar to local timezone
function displayDates() {
    document.addEventListener('DOMContentLoaded', function() {
        // Select all elements with data-datetime attribute
        const elementsWithData = document.querySelectorAll('[data-datetime]');

        // Convert NodeList to array for easier iteration
        const elementsArray = Array.from(elementsWithData);

        elementsArray.forEach(function(element, index) {
            // Get the value of data-datetime attribute
            const dateString = element.getAttribute('data-datetime');
            const utcTime = new Date(dateString);

            const timeString = utcTime.toLocaleTimeString('en-US', {
                hour: 'numeric',
                minute: 'numeric',
                hour12: true
            });

            // Get the time zone abbreviation
            const timeZoneAbbr = /((.*))/.exec(new Date().toString())[1];

            const finalFormattedDate = new Intl.DateTimeFormat('en-US', { weekday: 'long' }).format(utcTime) + ', at ' + timeString + ' (' + timeZoneAbbr + ')';

            // Set the formatted date in the corresponding span
            element.innerHTML = finalFormattedDate;
        });
    });
}

// Call the function
displayDates();

In the markdown file for the page, index.md, I write <span id="utcTimeX" data-datetime="YYYY-MM-DDTHH:MM:SSZ"></span> for some paticular date, which is then converted from UTC to the local timezone.

While everything works without issue, I have noticed that the converted date/times are noticeably slow to load upon refreshing the page. (When removing the script call from page.html, the page loads without issue.) Is there a way to fix this?


I originally had the script file in the index.md file, which I then moved to the head of page.html. I was hoping that this would fix things, but alas the issue was still present. I have also tried cache busting when calling the script, but that didn’t change anything. I’ve tried deleting the Gemfiles, but that didn’t do anything either.

I am wondering if the script could be made faster, or the desired text output in a better way. Alternatively, I wonder if I should be calling the script from a different location to improve the performance.

VS Code – Error: EPERM: operation not permitted problem when trying to update VS code

When I open VS code and try to check for update, I always encounter this problem.

EPERM: operation not permitted, mkdir 'C:PROGRA~2MINGW-~1I686-8~1.0-Pvscode-stable-user-x64'

enter image description here

It not only appeared when I tried to update VS code. It also shows up in the built in TypeScript and JavaScript Language Features extension. So I can’t use the IntelliSense, auto import, Etc.

EPERM: operation not permitted, mkdir 'C:PROGRA~2MINGW-~1I686-8~1.0-Pvscode-typescript'

enter image description here

Does anyone know how to fix this?