Im am having trouble with a javascript loop

The code is messy but what I am trying to achieve is creating a class with the value of “cool” by using loops.

I started by putting each of the paragraphs in each of their own variable and then I placed them in a loop where I stated that I wanted each of them to have a classname of “cool”, I also stated that I wanted this value i.e “cool” to display in the HTML just so that I can ensure that it is working, but is not going through and i would like to know what I am doing and/or you have a more efficient way of going about this.

    <p id="cool" style="margin-top:2rem; background-color:#b35900; padding:2rem; color:white;"></p>

    <p id="cool1" style="margin-top:2rem; background-color:#b35900; padding:2rem; color:white;"></p>

    <p id="cool2" style="margin-top:2rem; background-color:#b35900; padding:2rem; color:white;"></p>

    <p id="cool3" style="margin-top:2rem; background-color:#b35900; padding:2rem; color:white;"></p>

    <p id="cool4" style="margin-top:2rem; background-color:#b35900; padding:2rem; color:white;"></p>


    var i;
    var loop1 = document.getElementById("cool");
    var loop2 = document.getElementById("cool1");
    var loop3 = document.getElementById("cool2");
    var loop4 = document.getElementById("cool3");
    var loop5 = document.getElementById("cool4");

    var loops = [loop1, loop2, loop3, loop4, loop5];
    var loopsLng = loops.length;

    for (i = 0; i > loopsLng; i++) {
      document.getElementById(loops[i]).className = "cool";
      var one = document.getElementById(loops[i]).getAttribute ("class");
       document.getElementById(loops[i]).innerHTML = one;
    }

Is there a way to implement something like valueChanges for angular-fire, using http.get?

I am trying to incrementally pull new data from an API. The data is updated ever so often and I am using an http.get request to call the API. This makes it impossible at present without further code to update the view/application when the data from the API changes, since the request won’t know the data has been updated.

In angular I have this GET request


this.http
.get('linkto.api').subscribe(item => {
this.service_one.itemData = [item as any];
});

I would like something like valueChanges(), that is present in angular-fire

export class AppComponent {
  items: Observable<any[]>;
  constructor(db: AngularFireDatabase) {
    this.items = db.list('items').valueChanges();
  }
}

How to pass useState prop to another component after fetching data and modifying the data structure? Typescript

I’m receiving undefined in the child component. If I console.log from the parent, I can see all the data but something happens when I pass the prop. Is this incorrect the way I do it ?

Here I set useState as an array that takes in 2 strings like a dictionary.

export interface superclassInfo {
  class: string;
  id: string;
}
const [classid, setClassid] = useState<superclassInfo[]>([]);

I fetch the data, modify the data structure and store it as state.

 let newJob = { class: job1, id: job2 };
 setClassid((value) => [...value, newJob]);

This is working perfectly, when I console.log, I see an array of objects with class:string, id:string
I pass prop to child component RankingSubclass with the state. (I believe this is where the undefined comes from, probably doing it wrong here).

useEffect(() => {
  <RankingSubclass classes={classid} />;
}, [classid]);

In RankingSubclass (child component), I import the interface and use a functional component but the console.log is undefined here

interface ComponentProps {
  classes: superclassInfo[];

const RankingSubclass: React.FC<ComponentProps> = ({ classes }) => {

  useEffect(() => {
    console.log({ classes });
  });
}

Why different behavior between arguments object and arguments like object?

When I passed object like arguments’ object I receive an empty array. Why?

function checkArguments() {
    console.log(arguments)//[Arguments] { '0': 'first', '1': 'second' }
    console.log(Array.prototype.slice.call(arguments))//[ 'first', 'second' ]
    console.log(Array.prototype.slice.call({'0': 'first','1': 'second'}))// [] ? why empty array    
}
  
checkArguments("first", "second")

Technique to fit images several images within a max width/height in a grid?

I have been staring at this for about an hour, trying every permutation How to force image resize and keep aspect ratio? but none of it solves my case.

Here are two images which I’ve manually resized here so you can see them both at once:

highly vertical image

very much horizontal image

In theory, the vertical image can be 10,000+px tall, meanwhile the horizontal one can get to about 4,000px wide, or we can have 1 10000px tall image, and one 100px wide image, so the sizes can vary a great deal.

I would like to lay these out in a grid basically, where each image gets at most a square, and if it is tall, it can be squeezed/packed together on the x-axis. I think I want to lay them out something like this:

enter image description here

So it’s about a square 250x250px on all sides where an image can possibly go. If it’s too tall, shrink the image down and it gets put in a thinner horizontal space but fills the height. If it’s too short but too wide, it only grows to 250px. Otherwise the images are bottom aligned to the grid. They are in no particular order.

In my case, I am taking an ArrayBuffer or File object and converting it to the image, through the dataURI system, so I think I can get access to the actual width/height of the image and use that in any calculations that might be necessary. I am 80% sure this can’t be done in pure CSS (after that link above), so what sort of trick or simple algorithm could I use to lay the images out like this? Do I need to use JavaScript to make it happen? I have been at the general problem for a few hours.

Hey! I’m building a project “Tsp the numbers” and cannot understand why it does not run correctly

at the end of this code I get undefined instead of the print “Done!”
I cannot figure out why, I even tried to use the chatGPT to understand if there are any syntax issues, but none.
Here’s my code:

const gContainer = document.querySelector(".container")
const gTable = document.querySelector('table')
const gNumbers = []
var chosenNum
var chosenLength;


onInit()

function onInit() {
    userChoice()
}

function playGame() {
    var counter = 0
    if (counter === gCells.length) {
        console.log('Done!')
    } else {
        const gCells = document.querySelectorAll('td')
        chosenNum = drawNum()
        console.log(`The chosen number is ${chosenNum}! Tap it!`)
        // gCells[idxOfEl].style.backgroundColor = 'yellow'
        const idxOfCell = gNumbers.indexOf(chosenNum)
        if (gCells[idxOfCell].style.backgroundColor === 'red') {
            counter++
        }
        gNumbers.splice(idxOfCell, 1)
    }
}

function cellClicked(cell) {
    const numInsideCell = parseInt(cell.innerText)
    // const timestamp = new Date().toLocaleTimeString();
    if (numInsideCell === chosenNum) {
        console.log('Awesome!')
        cell.style.backgroundColor = 'red';
        playGame();
    } else {
        console.log('You tapped the wrong number.')
    }
}


function drawNum() {
    const idxOfEl = Math.floor(Math.random() * (gNumbers.length))
    return gNumbers[idxOfEl]
}


function addNumbers(numOfCells) {
    var randNum = 0
    var counter = 0
    while (counter < numOfCells) {
        randNum = Math.floor(Math.random() * (50 - 1) + 1)
        if (!gNumbers.includes(randNum)) {
            gNumbers.push(randNum)
            counter++
        } else continue
    }
}

// ------------

function userChoice() {
    var strHTML = ''
    strHTML += `
    <h1 style="text-align:center;margin:30px">Tap the numbers!</h1>
    <p>Please choose how many cells would you like to have:</p>
    <ul>
    <li onclick="displayBoard(this)">16</li>
    <li onclick="displayBoard(this)">25</li>
    <li onclick="displayBoard(this)">36</li>
    </ul>`
    gContainer.innerHTML = strHTML
}

function displayBoard(numOfCells) {
    chosenLength = parseInt(numOfCells.innerText)
    gTable.style.display = 'table'
    var chosenLength = parseInt(numOfCells.innerText)
    addNumbers(chosenLength)
    var counter = 0
    var strHTML = ''
    strHTML += `<tbody>`
    for (var i = 0; i < Math.sqrt(chosenLength); i++) {
        strHTML += `<tr>`
        for (var j = 0; j < Math.sqrt(chosenLength); j++) {
            strHTML += `<td data-location="${i}${j}" onclick="cellClicked(this)">${gNumbers[counter]}</td>`
            counter++
        }
        strHTML += `</tr>`
    }
    strHTML += `</tbody>`
    gTable.innerHTML = strHTML
    playGame()
}

html

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Number tapping Game</title>
    <link rel="stylesheet" href="css/style.css">
</head>

<body>
    <div class="container">
        
    </div>
    <div class="table"><table></table></div>
    <script src="js/code.js"></script>
</body>

</html>

Getting undefined at the last number instead of the print “Done!”
If you have any other improvements to suggest – I’d be glad to hear!

Displaying geojson data on a map after submiting form using PHP

I’m trying to display data on a leaflet map based on a form selector. My problem is that the data are not displayed after selecting the option.

I have an html file webiste.html, and two php files insert_data.php and read_data.php (might not be the most efficient thing in the world).

This is my selector :

<form action="" method="POST" enctype="multipart/form-data">
    <select onchange="submitForm(); changeData()" value="false" name="geo" id="geo" class="selectors myDropdown">
        <option value="base">Geo</option>
    </select>
</form>

These are the js functions that are activated when an option is selected :

var map = L.map('map').setView([45.505, -73.19], 9); // Set initial coordinates and zoom level
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'}).addTo(map);

//Submit the data and populate my postgresql table
//This one works
function submitForm() {
    var formData = {
        geo: $("#geo").val(),
    };
    console.log(formData)
    $.ajax({
        type: "POST",
        url: "insert_data.php",
        data: formData,
        dataType: "json",
        encode: true,
    }).done(function (data) {
    });
    event.preventDefault();
};
//read the data
function changeData(){
    var geoSelect = document.getElementById('geo');
    geo.setAttribute("value", "true")
    var geoSelect = document.getElementById('geo').getAttribute('value');
    if (geoSelect == 'true'){
        $.get("refresh_query.php", function(data){
        }); //this reset my postgresql table
        $.ajax({url:'read_data.php', //This is what seems to be the issue
            success: function(response){
            airbnbs = JSON.parse(response)
            lyr = L.geoJSON(airbnbs,{
            }).addTo(map)
            }   
        })
        var geoSelect = document.getElementById('geo');
        geoSelect.setAttribute("value", "false")
    }else{
    }
}

Finally, this is my read_data.php script :

<?php
$db = pg_connect("host=localhost dbname=db user=postgres password=xxxxx");

if (!$db) {
    echo "An error occurred.n";
    exit;
}


$sql = 'SELECT id, ST_AsGeoJSON((ST_SetSRID(ST_MakePoint(lng, lat), 4326)), 4) as geom 
        FROM data';

//pg_query("DELETE FROM data");
$query = pg_exec($db, $sql);
$features = [];
for ($i = 0; $i < pg_numrows($query); $i++) {
    $row = pg_fetch_assoc($query,$i);
    $geometry = $row['geom'] = json_decode($row['geom']);
    unset($row['geom']);
    // Nous retirons les résultats redondants
    unset($row[0]);
    unset($row[1]);
    unset($row[2]);
    unset($row[3]);
    unset($row[4]);
    // Nous reconstituons notre 'feature' sur le modèle GeoJSON
    $feature = ['type' => 'Feature', 'geometry' => $geometry, 'properties' => $row];
    array_push($features, $feature);
};
$featureCollection = ["type" => "FeatureCollection", "features" => $features];
echo stripslashes(json_encode($featureCollection, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
pg_close($db);
?>

Vite JS merge output sourcemaps

We’re using a vite for a project.
Works great and creates multiple chunks when building.

Recently i enabled sourcemaps and every chunk gets its individual .map file.

However, i’d like to have multiple chunks and just one combined/ merged sourcemap file that covers all chunks.

I couldn’t find anything related within the vite/ rollup documentation.

Register Calendar Component with React Form Hook

Hello I trying to register “Calendar” component from “Prime React” library with “React Form Hook”. The problem is that I can’t set default value to the input.

This is where I set the default value.

    const { register, handleSubmit, reset, formState: { errors }, control } = useForm({ mode: 'onSubmit', defaultValues: {
        title: "test",
        start: new Date(),
        end: new Date()
        
      } });

This is my component.

import React from 'react'
import { Calendar } from 'primereact/calendar';
import { useFormState } from 'react-hook-form';
import { CDatePickerStyled } from './CDatePicker.styled';

export default function CDatePicker({ required, disabled, register, control, placeHolder }) {
  const { errors } = useFormState({ control });
  return (
    <CDatePickerStyled>
      <Calendar className={errors[register.name] ? 'p-invalid' : ''} {...register} placeholder={placeHolder} disabled={disabled}></Calendar>
      {required ? <span className={errors[register.name] ? 'error' : ''}>Required*</span> : null}
    </CDatePickerStyled>
  )
}

React Native – Brief Flash of Splash Image After Lottie Animation Splash with Expo

I’m facing an issue in my React Native Expo project where a short flash of the splash image occurs after the completion of a Lottie animation during the app launch. I’ve attempted various approaches to synchronize the hiding of the native splash screen with the Lottie animation’s completion, but the issue persists.

To provide more context, the launch screen displays the same content as the first frame of the animated launch screen, and the transition at the start is functioning correctly. The problem only arises after the Lottie animation finishes.

Here’s an overview of my current implementation:

App.tsx:

import SignUp from "@views/auth/SignUp";
import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, View } from "react-native";
import { useEffect, useState } from "react";
import LottieAnimation from "@components/LottieAnimation";
import Animated from "react-native-reanimated";
import * as SplashScreen from "expo-splash-screen";

export default function App() {
  const [appIsReady, setAppIsReady] = useState(false);
  const [splashAnimationFinished, setSplashAnimationFinished] = useState(false);

  useEffect(() => {
    async function prepare() {
      try {
        // Pre-load fonts, make any API calls you need to do here
      } catch (e) {
        console.warn(e);
      } finally {
        // Tell the application to render

        setAppIsReady(true);
      }
    }

    prepare();
  }, []);

  if (!appIsReady || !splashAnimationFinished) {
    return (
      <LottieAnimation
        onAnimationFinish={(isCancelled) => {
          if (!isCancelled) {
            setSplashAnimationFinished(true);
          }
        }}
      />
    );
  }

  return (
    <Animated.View style={styles.container}>
      <SignUp />
      <StatusBar style="auto" />
    </Animated.View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

LottieAnimation.tsx:

import { FC } from "react";
import { StyleSheet, View } from "react-native";
import LottieView from "lottie-react-native";
import colors from "@utils/colors";
import Animated, { FadeOut, ZoomOut } from "react-native-reanimated";

interface Props {
  onAnimationFinish?: (isCancelled: boolean) => void;
}

const AnimatedLottieView = Animated.createAnimatedComponent(LottieView);

const LottieAnimation: FC<Props> = ({ onAnimationFinish }) => {
  return (
    <Animated.View style={styles.animationContainer} exiting={FadeOut}>
      <AnimatedLottieView
        //exiting={ZoomOut}
        autoPlay
        onAnimationFinish={onAnimationFinish}
        loop={false}
        style={{
          width: "80%",
          height: "100%",
        }}
        source={require("@assets/LogoAnimation.json")}
      />
    </Animated.View>
  );
};

const styles = StyleSheet.create({
  animationContainer: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center",
    backgroundColor: colors.PRIMARY,
  },
});

export default LottieAnimation;

Vue JS 2 component not displaying data after using v-if in Nuxt JS 2 project

I’m working in a Nuxt JS 2 project and have built a component called Calculator. This is loaded into my page which contains a HTML table. I have a button in the page that toggles the calculator, the variable to toggle is a boolean isCalculatorShown.

When my calculator component is initially toggled on everything works, but when the isCalculatorShown variable then gets switched from true back to false (essentially destroying the component) and then toggled on again, everything works apart from the output to the page of my formulas object.

Console logging in the calculateCells method shows me the correct values, yet trying to do this.formulas.* doesn’t update the one inside data(), what am I missing, here’s my Calculator component:

<template>
  <div class="calculator-wrapper">
    <b-button @click="closeCalculator" pill variant="white" size="sm" class="btn-close shadow">
      <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" stroke-width="1.5" stroke="currentColor" class="text-secondary">
        <path stroke-linecap="round" stroke-linejoin="round" d="M15 12H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z" />
      </svg>
    </b-button>
    <div class="sums p-1">
      <article>
        <div class="d-none d-md-flex">
          <ul class="list-group list-group-horizontal bg-transparent">
            <li class="list-group-item">Sum: {{ formulas.sum }}</li>
            <li class="list-group-item">Avg: {{ formulas.avg }}</li>
            <li class="list-group-item">Min: {{ formulas.min }}</li>
            <li class="list-group-item">Max: {{ formulas.max }}</li>
            <li class="list-group-item">Count: {{ formulas.count }}</li>
          </ul>
        </div>
        <div class="d-flex d-md-none">
          <select name="cell-calculations" class="custom-select">
            <option>Sum: {{ formulas.sum }}</option>
            <option>Avg: {{ formulas.avg }}</option>
            <option>Min: {{ formulas.min }}</option>
            <option>Max: {{ formulas.max }}</option>
            <option>Count: {{ formulas.count }}</option>
          </select>
        </div>
      </article>
      <div class="p-1">
        <b-button @click="clear" variant="dark" size="sm">Clear</b-button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    isCalculatorShown: {
      default: false,
      type: Boolean
    },
    dataScope: {
      default: 'td',
      type: String
    }
  },
  data () {
    return {
      calculator: null,
      table: null,
      cells: null,
      cellValues: [],
      formulas: {
        sum: 0,
        avg: 0,
        min: 0,
        max: 0,
        count: 0
      }
    }
  },
  mounted () {
    this.initCalculator()

    for (const cell of this.cells) {
      cell.addEventListener('click', (event) => {
        this.getCellValue(cell)
      })
    }
  },
  methods: {

    /*
    ** Init calculator
    */
    initCalculator () {
      this.calculator = document.querySelector('.calculator-wrapper')
      this.table = document.getElementById('main-report')

      if (!this.table) return

      this.cells = this.table.querySelectorAll(this.dataScope)
    },

    /*
    ** Calculate value of selected table cells
    */
    calculateCells (val) {
      // TODO: this.formulas never seems to update one in data() after component v-if toggled
      this.formulas.sum = val.map(Number).reduce((a, b) => a + b, 0).toFixed(2)
      this.formulas.avg = (val.reduce((a, b) => a + b, 0) / val.length).toFixed(2)
      this.formulas.min = Math.min(...val)
      this.formulas.max = Math.max(...val) || 0
      this.formulas.count = val.length || 0
    },

    getCellValue (cell) {
      const SANITISED_REGEX = /^£|,|%|s|([^)]*) */g
      const trimmedCellValue = cell.innerText.trim().replace(/^-£|£-/g, '-')
      const firstCellValue = this.getFirstCellValue(trimmedCellValue)

      if (firstCellValue) {
        const sanitisedValue = firstCellValue.replace(SANITISED_REGEX, '')

        if (
          this.isNumeric(sanitisedValue) &&
          !cell.classList.contains('highlight-cell')
        ) {
          this.cellValues.push(sanitisedValue)
          cell.classList.add('highlight-cell')
          this.calculateCells(this.cellValues.map(Number))
        }
      } else {
        if (
          this.isNumeric(trimmedCellValue.replace(SANITISED_REGEX, '')) &&
          !cell.classList.contains('highlight-cell')
        ) {
          cell.classList.add('highlight-cell')
          this.cellValues.push(trimmedCellValue.replace(SANITISED_REGEX, ''))
          this.calculateCells(this.cellValues.map(Number))
        }
      }

    },

    /*
    ** Check if selected cell is a number
    */
    isNumeric (str) {
      if (typeof str != 'string') return false
      return !isNaN(str) && !isNaN(parseFloat(str))
    },

    /*
    ** Return first value if there are multiple within the table cell
    */
    getFirstCellValue (cell) {
      return cell.split('  ')[0]
    },

    /*
    ** Close calculator
    */
    closeCalculator () {
      this.$emit('onClose', true)
      this.clear()
    },

    /*
    ** Clear any selected values
    */
    clear () {
      this.cellValues = []

      this.formulas.sum = 0
      this.formulas.avg = 0
      this.formulas.min = 0
      this.formulas.max = 0
      this.formulas.count = 0

      for (const cell of this.cells) {
        cell.classList.remove('highlight-cell')
        cell.removeEventListener('click', this.getCellValue)
      }

    }

  }
}
</script>

And it’s loaded at the page level with:

<Calculator v-if="isCalculatorShown" @onClose="isCalculatorShown = false" />

Is there a way to get the title of a cross-origin sandboxed iframe’s document?

I am making a basic web browser, written in HTML. I’d like to access the title of the document, so that you can see it like a tab in a normal browser. Usually, you can use iframe.contentDocument.title, but my iframe is cross-origin and sandboxed so this doesn’t seem to work. Is there a way that you can access the title anyway, or is this impossible?

Here’s an example:

const iframe = document.querySelector("iframe");
const span = document.querySelector("span");

document.querySelector("iframe").addEventListener("load", function() {
  const title = iframe.contentDocument.title; // contentDocument is null
  span.innerText = title;
});
body {
  display: flex;
  flex-direction: column;
  margin: 0;
  height: 100vh;
}

iframe {
  flex-grow: 1;
}
<h1>Title: <span id="title"></span></h1>
<iframe src="https://www.bing.com" sandbox="allow-scripts"></iframe>

Javascript text input won’t update based on 2D-array

I am working on a React function to print a Sudoku board and allow the user to fill it in.

The function printSudoku() is used to return the board to the body of the webpage and display the contents. If a cell has been given a predefined value for the puzzle, the box is disabled to stop the user from editing the contents, otherwise it is accessible.

function printSudoku(puzzle){
    const board = puzzle[1];
    
    return (
      <div id="Puzzle-grid">
        {board.map((row, i) => (
          <div key={i}>
            {row.map((cell, j) => (
              <input type="text" key={j} value={cell === '' ? userSolution[i][j]: cell} className="Puzzle-cell" disabled={cell !== ''}
              style={{backgroundColor: (((j < 3 || j >= 6) && (i < 3 || i >=6)) || (j >= 3 && j <6 && i >=3 && i < 6)) ? 'lightgray' : 'white', fontWeight: (cell !== '') ? 'bolder' : 'normal'}}
              onChange={(e) => updateUserSolution(e.target.value, i, j, userSolution)}/>
            ))}
          </div>
        ))}
      </div>
    );
  }

The next function is what is called upon change in an enabled cell, updateUserSolution(). This function takes the positioning of the cell from the Puzzle-grid and saves the contents to a 2D-array. This 2D-array is then used to overwrite the previous userSolution 2D-array with the new information.

function updateUserSolution(cell, rowIndex, colIndex, puzzle){
    const grid = userSolution;
    grid[rowIndex][colIndex] = cell;
    setUserSolution(grid);
    console.log(grid);
  }

The expected result is that the page will update to reflect the value of the userSolution 2D-array. However, the result is that the entered value is reflected in the 2D-array, but never in the table. I have tried other methods as well, such as using defaultValue for the given values and value only for the user input, which allows the input to be reflected, but results in issues upon generating a new puzzle. Any input would be greatly appreciated. If any further context is needed, I’d be happy to provide what I can.

Trying to download a instance of “Blob” created from “new Audio().buffer” but the file is strange

I have a small app where it’s possible to listen to a distorted preview of a recording. After that it should be possible to download it.

My playSound function works as expected and then I try to return the “source” which is just an instance of the Audio class so I can later download it.

let audioCtx;
let source;
let myBuffer;
let songLength;
let request;

function playSound(
  file,
  speed = 1,
  pitchShift = 1,
  loop = false,
  autoplay = true
) {
  if (pitchShift) {
    audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    source = audioCtx.createBufferSource();
    request = new XMLHttpRequest();

    request.open("GET", file, true);

    request.responseType = "arraybuffer";

    request.onload = function () {
      var audioData = request.response;

      audioCtx.decodeAudioData(
        audioData,
        function (buffer) {
          myBuffer = buffer;
          songLength = buffer.duration;
          source.buffer = myBuffer;
          source.playbackRate.value = speed;
          source.connect(audioCtx.destination);
          source.loop = loop;
        },

        function (e) {
          "Error with decoding audio data" + e.error;
        }
      );
    };

    request.send();
    source.play = source.start;
  } else {
    source = new Audio(file);
    source.playbackRate = speed;
    source.loop = loop;
  }
  if (autoplay) {
    source.play();
  }
  return source;
}

When the playSound function is called I attach the returned source to the window.audioSource so I am able to download it later

document.getElementById("preview").addEventListener("click", function () {
  const audioSource = playSound("test.mp3", (pitch = 0.5));

  // Save the audio source for later use
  window.audioSource = audioSource;
});

Then in the “Download” event listener I try to finally turn the buffer of the audioSource into a blob and download it. It seems to work until I try to play the file where it complains about the format not being correct.

document.getElementById("download").addEventListener("click", function () {
  // Check if there's an audio source
  if (window.audioSource) {
    const audioBlob = new Blob([window.audioSource.buffer], {
      type: "audio/mp3",
    });
    console.log(audioBlob);

    const url = URL.createObjectURL(audioBlob);

    // Create a download link and trigger a click to download the file
    const a = document.createElement("a");
    a.href = url;
    a.download = "downloaded_audio.mp3";
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  }
});

When I try to console.log the blob it seems the size is pretty small so I am guessing this is where everything goes wrong.

Blob {size: 20, type: 'audio/mp3'}size: 20type: "audio/mp3"[[Prototype]]: Blob

Getting many audio on the current browser tab using javascript

I’m having trouble getting audio on the current browser tab using javascript. I don’t know if there’s a way to get continuous audio responses back to the system using the API. Thank you. I tried with navigator.mediaDevices.getDisplayMedia () function onAccessApproved(stream){
const options = {
audioBitsPerSecond: 128000,
videoBitsPerSecond: 2500000,
mimeType: “video/webm”, // Changed to a valid MIME type
};
recorder = new MediaRecorder(stream, options);

 recorder.ondataavailable = function(event){
     let recordedBlob = event.data
     let url = URL.createObjectURL(recordedBlob)

     let a = document.createElement("a");

     a.style.display = "none";
     a.href = url;

     // Generate a random number from 1 to 1000
     var random_number = Math.floor(Math.random() * 1000) + 1;

     // Get the current time to generate part of the random name
     var timestamp = new Date().getTime();

     // Generate random names by combining random numbers and times
     var random_name = "screen-recording_" + random_number + "_" + timestamp + ".webm";

     // Set value for download attribute
     a.download = random_name;

     // a.download = "screen-recording.webm"; // Changed to match the MIME type
     document.body.appendChild(a)
    
     a.click();

     document.body.removeChild(a);

     URL.revokeObjectURL(url);
 }


 recorder.start(1000);

}
Every 1 second, the video will be downloaded once, but the card with the first video can be opened and the other videos will have an error.

Every 1 second, the video will be downloaded once, but the card with the first video can be opened and the other videos will have an error.