How to run async function in parallel but with a timeout after the first one resolves? | Promise.all with timeout after first resolves

Let’s say I have async functions calling external APIs with variable response times defined as below:

async function promise1() { /* API Call */ }
async function promise2() { /* API Call */ }
async function promise3() { /* API Call */ }
// ... up to promiseN

If I wanted to run them all in parallel and wait for all of them to resolve, I would run them like result = Promise.all([promise1, promise2, promise3,...,promiseN]).

However, I have a slightly different requirement:

  1. I want to start all the promises in parallel.
  2. As soon as the first one resolves (whichever that is), I want to wait 500 milliseconds for the other promises to resolve.
  3. After that 500 ms window, I want to ignore any remaining unresolved promises.
  4. result should contain all the promises that resolved by the time the 500 ms window ends.

So for example, if promise2 resolves first at time T, I want to wait until T + 500 ms for the others to resolve. Any promises that haven’t resolved by then should be ignored.

How can I accomplish this in JavaScript?

Frappe gantt stopped working, error giving as Gantt not defined,

I am using the frappe gantt chart library in my html file, it was all working fine till 13th sep 2024, after that it suddenly throwing me error as –
Gantt not defined, though I’ve used online cdn links of the library, those are fine, it was working fine with that same link before, can anyone guide me what to be done to fix this?
Need urgent resolution on this.I have tried to add this locally and then use it, it is still the same, in network tab I can see it is loading

links I am using –

I have tried to add that library locally, then as well I saw in my network tab the frappe gantt library is loading, it was working fine, after a release it stopped working from friday.

here this error is coming on loading of the gantt chart library, error coming as below, though in network tab we can see that.

jira/:338 Error initializing Gantt chart: ReferenceError: Gantt is not defined
    at HTMLDocument.<anonymous> (jira/:283:21)
    at e (jquery-3.6.0.min.js:2:30038)
    at t (jquery-3.6.0.min.js:2:30340)

code snippet –

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Frappe Gantt Chart Example</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/frappe-gantt/dist/frappe-gantt.css">
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 20px;
    }

    #gantt {
      height: 500px;
      overflow: auto; /* Allow scrolling if needed */
    }
  </style>
</head>

<body>
  <h2>Gantt Chart Example</h2>
  <div id="gantt"></div>

  <script src="https://cdn.jsdelivr.net/npm/frappe-gantt/dist/frappe-gantt.js"></script>
  <script>
    document.addEventListener('DOMContentLoaded', function () {
      const tasks = [
        {
          id: "Task 1",
          name: "Task 1",
          start: "2023-09-01",
          end: "2023-09-05",
          progress: 100,
        },
        {
          id: "Task 2",
          name: "Task 2",
          start: "2023-09-03",
          end: "2023-09-10",
          progress: 50,
        },
        {
          id: "Task 3",
          name: "Task 3",
          start: "2023-09-06",
          end: "2023-09-12",
          progress: 25,
        },
      ];

      const gantt = new Gantt("#gantt", tasks, {
        on_click: (task) => {
          alert(`Task: ${task.name}`);
        },
        on_date_change: (task, start, end) => {
          console.log(`Task date changed: ${task.name} from ${start} to ${end}`);
        },
      });
    });
  </script>
</body>

</html>

Autoscale plotly chart using github, Javascript, html

I want to plot plotly chart on github pags. I am using html code and javascript. I am able to plot the chart but it is not autoscaling. Below is the code. First part is doing fine.

let data = {};

// Function to update message on the screen
function displayMessage(message) {
const messageDiv = document.getElementById("message");
messageDiv.innerHTML = message;
}

// Function to load and merge multiple JSON files
function loadData() {
const jsonFiles = ['data_1d_part_22.json', 'data_1d_part_9.json'];

const fetchPromises = jsonFiles.map(file => fetch(file).then(response =>        response.json()));

Promise.all(fetchPromises)
    .then(jsonParts => {
        // Merge all parts into the 'data' object
        jsonParts.forEach(part => {
            Object.assign(data, part);
        });
        displayMessage("All data successfully loaded from JSON files.");
    })
    .catch(error => displayMessage('Error loading JSON files: ' + error));
}

// Call loadData when the page loads
window.onload = loadData;

function plotGraph() {
const tick = document.getElementById("search-box").value.trim();

if (!tick) {
    displayMessage("Please enter a tick.");
    return;
}

if (tick in data) {
    const tickData = data[tick];
    displayMessage(`Data found for tick: ${tick}`);

    // Extract the necessary data
    const dates = tickData.map(entry => entry.Datetime);
    const opens = tickData.map(entry => entry.Open);
    const highs = tickData.map(entry => entry.High);
    const lows = tickData.map(entry => entry.Low);
    const closes = tickData.map(entry => entry.Close);
    const volumes = tickData.map(entry => entry.Volume);
    const k_values = tickData.map(entry => entry.k);
    const d_values = tickData.map(entry => entry.d);
    const signals = tickData.map(entry => entry.signal);

    // Candlestick trace
    const candlestick = {
        x: dates,
        open: opens,
        high: highs,
        low: lows,
        close: closes,
        type: 'candlestick',
        name: 'Price',
        xaxis: 'x',
        yaxis: 'y1'
    };

    // K and D oscillator traces
    const k_trace = {
        x: dates,
        y: k_values,
        mode: 'lines',
        name: 'K',
        line: { color: 'blue' },
        xaxis: 'x',
        yaxis: 'y2'
    };

    const d_trace = {
        x: dates,
        y: d_values,
        mode: 'lines',
        name: 'D',
        line: { color: 'orange' },
        xaxis: 'x',
        yaxis: 'y2'
    };

    // Volume bar chart trace
    const volume_trace = {
        x: dates,
        y: volumes,
        type: 'bar',
        name: 'Volume',
        marker: { color: 'rgba(100, 150, 250, 0.4)' },
        xaxis: 'x',
        yaxis: 'y3'
    };

    // Buy/Sell signals (arrows)
    const buy_signal_trace = {
        x: dates.filter((_, i) => signals[i] === 'Buy'),
        y: lows.filter((_, i) => signals[i] === 'Buy').map(low => low * 0.98),
        mode: 'markers',
        name: 'Buy Signal',
        marker: {
            symbol: 'triangle-up',
            color: 'green',
            size: 12
        },
        xaxis: 'x',
        yaxis: 'y1'
    };

    const sell_signal_trace = {
        x: dates.filter((_, i) => signals[i] === 'Sell'),
        y: highs.filter((_, i) => signals[i] === 'Sell').map(high => high * 1.02),
        mode: 'markers',
        name: 'Sell Signal',
        marker: {
            symbol: 'triangle-down',
            color: 'red',
            size: 12
        },
        xaxis: 'x',
        yaxis: 'y1'
    };

    // Layout for the chart
    const layout = {
        title: `Stock Data for ${tick}`,
        height: 800,
    dragmode: 'zoom',
        grid: {
            rows: 3,
            columns: 1,
            pattern: 'independent',
            roworder: 'top to bottom'
        },
        xaxis: {
            
            autorange: true,
            rangeslider: { visible: true },  // Disable the date slider
            range: [dates[dates.length - 50], dates[dates.length - 1]],  // Initial fixed range (last 50 dates)
            showticklabels: false,  // Remove date labels on the x-axis
        },
        yaxis1: {
            title: 'Price',
            autorange: true,
            domain: [0.5, 1],  // Height for candlestick panel
            anchor: 'x'
        },
        yaxis3: {
            title: 'Oscillator',
            autorange: true,
            domain: [0.2, 0.45],  // Height for K and D oscillator panel
            anchor: 'x'
        },
        yaxis2: {
            title: 'Volume',
            autorange: true,
            domain: [0, 0.19],  // Height for volume panel
            anchor: 'x'
        },
        showlegend: true,
        hovermode: 'x',  // Enable hovermode for dates to be shown only on hover
    };

    // Plot the chart
    Plotly.newPlot('plot', [candlestick, k_trace, d_trace, volume_trace, buy_signal_trace, sell_signal_trace], layout, {showSendToCloud: true});
    displayMessage(`Plot created successfully for ${tick}.`);
} else {
    displayMessage(`No data found for tick: ${tick}`);
}
};

This is the second part of the code that I added for auto scaling of plotly chart but it doesn’t seem to work.

var myPlot = document.getElementById('plot');

var isUnderRelayout = false;
myPlot.on('plotly_relayout',function(relayoutData){

if(isUnderRelayout != true)
    {
        isUnderRelayout = true;         
        
        // get the start and end dates of current 'view'
        var start = relayoutData['xaxis.range'][0];
        var end = relayoutData['xaxis.range'][1];   
        
        // get the index of the start and end dates
        var xstart = myPlot.data[0].x.map(function(e) { return e; }).indexOf(start.substring(0, 10));
        var xend = myPlot.data[0].x.map(function(e) { return e; }).indexOf(end.substring(0, 10));
        
        if (xstart < 0) { xstart = 0;} // sometimes the date is before the data and returns -1          
                    
        // get the min and max's
        var low = Math.min.apply(null, myPlot.data[0].low.slice(xstart, xend));
        var high = Math.max.apply(null, myPlot.data[0].high.slice(xstart, xend));
        
        // update the yaxis range and set flag to false
        var update = {'yaxis.range': [low, high]};  
        Plotly.relayout(myPlot, update).then(() => {isUnderRelayout = false})   
    }
 });

Is this the right method or should I try some other approach?

How would we get values in Preline Tailwind CSS ComboBoxes whenever selection updated?

I’m using pure HTML+JS+PrelineCSS and I have this code copied from here Example 1 a basic usage of ComboBox its working perfectly, however how would we get the value of the input whenever it changes? the value is always empty when we change selection unless it gets the focus!

I tried this <svg onclick="testValue2()" to force the input refocus:

function forcefocus() {
    document.getElementById("input1").focus();
}

It is working but it gives always the old value which means it is not ok! :s

Is there away or different approach to get the value on a function like this <input onblur="testValue(this)":

function testValue(el) {
    console.log(el.value);
    console.log(document.getElementById("input1").value); 
} 

The aim here to ( get the input ) then verify it before using/posting. So how would we get it please?

JSDOM unit testing

I have a project that calculates the distance between 2 semitones and I’m building a UI for it.

One of the things I have to do is have unit tests that make sure the game runs as it should.

I have run into an issue where one test keeps failing and I don’t understand why it’s failing.

For context, here is how the class works:
The JamBuddy class manages musical notes, allowing users to set current notes, validate them, and calculate distances between two notes in both clockwise and anticlockwise

let buddy = new JamBuddy();
buddy.setCurrentNotes(["D#", "C"]);
console.log(buddy.calculateDistance()); // Output: [10, 2] (clockwise and anticlockwise distances between D# and C)

Here is what I have so far:

I have this function that updates the UI with the relevant error or success message depending on if the user got the answer correct. It works as it should.

function checkCorrectAnswer() {
  const answer = parseInt(answerInputElement.value, 10);

  resultElement.textContent = "";

  if (answer.toString().includes(".")) {
    resultElement.textContent = errorMsgObj.answerFloat;
    clearDisplay();
  } else if (answer < 0) {
    resultElement.textContent = errorMsgObj.answerPositive;
    clearDisplay();
  } else if (answer > 12) {
    resultElement.textContent = errorMsgObj.invalidNumberRange;
    clearDisplay();
  } else {
    const isCorrectAnswer = jamBuddy.checkAnswer(answer);

    if (isCorrectAnswer) {
      resultElement.textContent = successMsgObj.correctAnswerMsg(answer);
      answerInputElement.disabled = true;
      checkAnswerBtn.disabled = true;
      streakCounterHandler();
      streakDisplay.innerHTML = `Current Streak: ${streakCounter}`;
    } else {
      resultElement.textContent = errorMsgObj.incorrectAnswer;
      answerInputElement.disabled = false;
      checkAnswerBtn.disabled = false;
      clearDisplay();
    }
  }
}

Here is my unit test:

it("should display a success message when the answer is correct when you click the check answer button", () => {
    jamBuddy.setCurrentNotes(["F", "A#"]);

    const [ans, ans1] = jamBuddy.calculateDistance();

    // Test the first possible answer
    answerInput.value = ans;
    checkAnswerBtn.click();
    clock.tick(1000);

    expect(resultElement.textContent).toBe(successMsgObj.correctAnswerMsg(ans)); //"Correct answer!"

The test fails expecting the resultElement.textContent to have “Incorrect Answer”

Where did I go wrong?

I tried re-writting the function using a switch statement but to no avail.

How can I get the test to pass?

CodeMirror Merge – Calling a Function on Chunk Approval/Reject

I am using CodeMirror 6, and the @codemirror/merge package. So far I’ve gotten everything UI related working. However, I can not figure out how to trigger a function when the user has either approved or rejected a code chunk.

Here is what my (JS/React) code looks like:

const editorState = EditorState.create({
  doc: modifiedCode,
  extensions: [
    ...extensions,
    showMergeView ? unifiedMergeView({ original: originalCode }) : [],
  ],
});

const view = new EditorView({
  state: editorState,
  parent: editorRef.current,
});

For reference, I want to run a function to know when to turn off merge view. I am doing this by counting the number of chunks returned by getChunks. However, I can not for the life of me figure out how to run a function when the user has interacted with the merge control buttons.

Loading a worker script at build time in a Vite project

Is it possible to create define a web worker such that it does not have to load from an external file during runtime in a vite project?
I am building a browser that depends on a web worker file and I want to build into one index.js asset file that can be used outside of the project. The problem is that I will need to deploy the index.js asset file along with the web worker file since it is being loaded through the URL.
Is there away to allow the web worker’s logic to be included into the final index.js file such that it can be defined and loaded from within the same index.js asset file?

My npm run start and some other npm comands are not working n new system

I changed to new HP Elitebook laptop, and i moved my files and projects there, and now i have been tryig to run ‘npx parcel index.html’ command in the vscode terminal.

I tried ‘npm run start’ and i was expecting to get a dist file and a localhost server powered by parcel but I keep getting this error:

`Error: The specified module could not be found.
\?C:UsersCHIEMERIE EREGEDesktopstarternode_modules@parcelsource-                    mapparcel_sourcemap_nodeartifactsindex.win32-x64-msvc.node
    at Module._extensions..node (node:internal/modules/cjs/loader:1586:18)
    at Module.load (node:internal/modules/cjs/loader:1288:32)
    at Module._load (node:internal/modules/cjs/loader:1104:12)
    at Module.require (node:internal/modules/cjs/loader:1311:19)
    at require (node:internal/modules/helpers:179:18)
    at Module._compile (node:internal/modules/cjs/loader:1469:14)
    at Module._compile (node:internal/modules/cjs/loader:1469:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1548:10)
    at Module.load (node:internal/modules/cjs/loader:1288:32)
  at Module._load (node:internal/modules/cjs/loader:1104:12) {
  code: 'ERR_DLOPEN_FAILED'
}`

and some other parcel / command prompt commands are not working too. Please what could be the problem?

How to make my function so it can run automatically even when the webpage is not currently active (run the function in background basically)

have a list, in which the names of the songs I want to play are placed in an order…when i have to play the next one, my function gets the currently playing song’s index, and plays the next one in the list..

toPlay = autoPlayOrder[(autoPlayOrder.indexOf(playing)) + 1]
play(toPlay)

here,

  1. autoPlayOrder is the list which has the songs to play
  2. playing is the song which is currently playing
  3. play() is a function I have that just plays the song

Now the system works as expected when the page is loaded but when im on another webpage, then when the song stops the next one isnt autoplayed…im guessing this is due to the reason that javascript isnt allowed to run when the page is not active

Just another side note, I was almost facing the same issue when i tried to make a loop song feature, but managed to work around that by using the inbuilt loop feature in an audio element in html..

Thanks!

Detect when tab is closed with Electron’s shell.openExternal

I am using Electron’s shell.openExternal(url) to open a new tab in the OS’s default browser from an Electron app. I would like to know if there is a way to detect events on that tab from the Electron app, specifically whenever the tab is closed.

The main reason I would like to detect this change is because I am calling a Node child_process, that starts a local web server on localhost:5000, and I would like to open a browser tab automatically to see the web server’s interface, but after the user closes the tab I would like to stop the child_process.

Is this possible with shell.openExternal?

Setting class with class binding through pipe

Having a problem with setting a class via custom pipe that I wrote.

I use signal Store that I map over to check if the value is matched with id in the store and if the condition is true, then if it’s true return one class, if not then return different class.

Store:

const initialState: LightboxState = {
  isActive: [
    { id: 'singleSided', status: false },
    { id: 'doubleSided', status: false },
    { id: 'illuminated', status: false },
    { id: 'notIlluminated', status: false },
    { id: 'standing', status: false },
    { id: 'hanging', status: false },
  ],

Pipe:

@Pipe({
  name: 'setClass',
  standalone: true,
  pure: false,
})

export class setClassPipe implements PipeTransform {
  private store = inject(LightboxStore);

  transform(value: string) {
    this.store.isActive().map((id) => {
      console.log(id.id);
      if (value === id.id && id.status === true) {
        console.log(id.status);
        return 'btn-active';
      }
      console.log(id.status);
      return 'btn-not-active';
    });
  }
}

template:

<button
  type="button"
  class="shadow"
  (click)="changeStatus('singleSided', 'doubleSided')"
  [class]="'singleSided' | setClass"
>
  JEDNOSTRONNY
</button>

The function reads properly value, id.id and id.status, but does not set any kind of class to the buttons even if initially it’s false

d3js semi-pie chart with a seamless wiggle rainbow color pattern

I am experimenting with different styles for charts – and I am wondering how to create these kind of pattern textures charts for the different segments with rounded gapped edges.

enter image description here

my current build — regular arc

I’ve seen this example in making a pattern – how would you make this wiggly multi-colored pattern that covers the arcs – almost like its cut out and there is this pattern behind it

https://codesandbox.io/p/sandbox/magical-wiles-forked-hdpq79

import React from "react";
import * as d3 from "d3";
import "./SemiPieChart1.scss";

class SemiPieChart extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
    this.state = {
      data: [],
      theme: this.props.theme
        ? this.props.theme
        : ["#bde0fe", "#2698f9", "#71bcfd", "#f1f8fe"],
    };
  }

  componentDidMount() {
    var $this = this.myRef.current;

    d3.select($this).selectAll("svg").remove();

    const data = this.props.data;

    const width = parseInt(this.props.width, 10),
      height = parseInt(this.props.height, 10),
      radius = parseInt(this.props.r, 10),
      innerradius = parseInt(this.props.ir, 10);

    var color = d3.scaleOrdinal().range(this.state.theme);

    var arc = d3.arc().outerRadius(radius).innerRadius(innerradius);

    data.forEach(function (d) {
      d.total = +d.value;
    });

    var pie = d3
      .pie()
      .startAngle(-90 * (Math.PI / 180))
      .endAngle(90 * (Math.PI / 180))
      .padAngle(0.02) // some space between slices
      .sort(null)
      .value(function (d) {
        return d.total;
      });

    var svg = d3
      .select($this)
      .append("svg")
      .attr("width", width)
      .attr("height", height)
      .append("g")
      .attr("class", "piechart")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

    var segments = svg.append("g").attr("class", "segments");

    var slices = segments
      .selectAll(".arc")
      .data(pie(data))
      .enter()
      .append("g")
      .attr("class", "arc");

    slices
      .append("path")
      .attr("d", arc)
      .attr("fill", function (d, i) {
        return color(i);
      })
      .transition()
      .attrTween("d", function (d) {
        var i = d3.interpolate(d.startAngle + 0.1, d.endAngle);
        return function (t) {
          d.endAngle = i(t);
          return arc(d);
        };
      });
  }

  render() {
    return <div ref={this.myRef} className="SemiPieChart" />;
  }
}
export default SemiPieChart;

<!DOCTYPE html>
<html>
<head>
    <style>
        
    </style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="hook"></div>
<script type="text/javascript">
        // SVG injection:
var svg = d3.select("#hook").append("svg").attr("id", "d3svg")
    .attr("width", 120)
    .attr("height", 120);
//Pattern injection
var defs = svg.append("defs")
var pattern = defs.append("pattern")
        .attr({ id:"hash4_4", width:"8", height:"8", patternUnits:"userSpaceOnUse", patternTransform:"rotate(-45)"})
    .append("rect")
        .attr({ width:"4", height:"8", transform:"translate(0,0)", fill:"#88AAEE" });

//Shape design
svg.append("g").attr("id","shape")
    .append("circle")
.attr({cx:"60",cy:"60",r:"50", fill:"url(#hash4_4)" })
    </script>
</body>
</html>

Multiple eCharts graphs in one page and data mapping / [ECharts] `setOption` should not be called during main process

I’m trying to put multiple charts of eCharts in one page of only one type with series like (type: 'line') but datas should be formatted according to different parameters for each graph.

For a single graph it is quite simple using:

option = {
    dataset: {
        source: datamapping(data),
    },
    //...
}

where datamapping it’s a function like

function datamapping(data){
   var parameter_used_for_data_mapping = 'serverSideAssignmentVariable'; //this is important
   data.map(item => [ otherFunctionForMapping(item[0], parameter_used_for_data_mapping) ,item[1] ]); // mapping time: (uses parameter_used_for_data_mapping for xAxis)
   return data;
}

But when I have multiple graphs I can’t use the same function datamapping(data) because each graph has a different parameter var parameter_used_for_data_mapping to map data.

I would get a javascript error telling me that there are multiple functions with the same name if I create one for each graph (server side). Also option wouldn’t know which function it was referencing since they would all have the same name.


So you need a callback function like:

option = {
    dataset: {
        source: (data) => {
           var parameter_used_for_data_mapping = 'serverSideAssignmentVariable';
           //here inside the datamap
           return data;
        },
    },
    //...
}

But if I do something like this I got a big red error in console that has been bothering my eyes for hours and hours

[ECharts] `setOption` should not be called during main process.

Now the real question:

How can you map data for multiple charts differently in such a condition?

Javascript Rounding Off For Positive & Negative Values?

I am trying to build a function that can return correct rounding off for both positive and negative values.

Here is my requirement

Input       Output
-1.8550     -1.86
1.8550       1.86
-1384.8540   -1384.85
1384.8540     1384.85
-1384.8550   -1384.86
-1384.8560   -1384.86
-3203.8640   -3203.86 

I tried below, but its not working.!

var customRoundOff = function(value) {
  debugger;
  var valueSign = Math.sign(value);
  var numericalPart = Math.abs(Number((value + "").split(".")[0]));
  var decPart = (value + "").split(".")[1];

  if (decPart && numericalPart) {
    var pntedDecimal = Number('0.' + decPart);
    var roundedDecimal = pntedDecimal.toFixed(2);
    var roundedValue = numericalPart + roundedDecimal;
    
    console.log("pntedDecimal", pntedDecimal);
    console.log("roundedDecimal", roundedDecimal);
    console.log("numericalPart", numericalPart);
    console.log("roundedValue", roundedValue);
    
    return roundedValue * valueSign; // Returns float
  } else {
    return value.toFixed(2); // Returns string
  }
}

customRoundOff(-1.8550);