Add an event listener to the first button that changes the text within the to EITHER uppercase or all lowercase

Hello code friends I have an assignment, new to this

Add an event listener to the first button that changes the text within the to EITHER all uppercase or all lowercase, depending on current state.

I need to change all paragraph under h1 to lowercase or uppercase, at the click of a button.

in HTML
I made an id to p.

I made a button with an id

in JS
I used getElementById to bring my button and paragraph.

const textChange = document.getElementById(“btnChange1”);
console.log(textChange);

const txtChange = document.getElementById(“myP”);

textChange.addEventListener(“click”, () => {

}
});

that’s as far as I can get, thanks in advance!

Is there a way to convert a blob with MIME type ‘audio/wav’ into a WAV file?

I am building an electron app that requires recording audio and saving it in the directory of my main.js. I got the recording as a blob and then turned it into an array buffer in order to send it to my backend.

In the startRecording function I use the mediarecorder to save the audio and then send it to main

const startRecording = async () => {
  console.log('Recording started');
  chunks = [];
  const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
  mediaRecorder = new MediaRecorder(stream);
  mediaRecorder.ondataavailable = event => {
      chunks.push(event.data);
  };
  mediaRecorder.onstop = () => {
      const blob = new Blob(chunks, { type: 'audio/wav' });

      // Convert Blob to buffer
      blob.arrayBuffer().then(buffer => {
          // Sending audio data to the main process using the function exposed in the preload script
          window.sendAudioToMain.send(buffer);
      }).catch(error => {
          console.error('Error converting Blob to buffer:', error);
      });

      const audioUrl = URL.createObjectURL(blob);
      const audioElement = document.getElementById('audioElement');
      audioElement.src = audioUrl;
  };
  mediaRecorder.start();
};
ipcMain.on('save-audio', async (event, buffer) => {
  try {
    // Convert the buffer back into a Blob
    const audioBlob = new Blob([buffer], { type: 'audio/wav' });

    // Print the MIME type of the blob
    console.log('MIME Type:', audioBlob.type);
} catch (error) {
    console.error('Error:', error);
}
});

In my code block I have the array buffer turned back into a blob, but what I would really like to know is how I can convert this into a wav file

conditional typing issue in typescript + react?

I am getting below error

Type ‘{ error: false; }’ is not assignable to type ‘x’.
Type ‘{ error: false; }’ is missing the following properties from type ‘ErrorWithMessage2’: name, message

I am trying to add conditional tying error: true then errorMessage is required
else error: false errorMessage is non mandatory

interface Error {
  error: boolean;
}

interface ErrorWithMessage extends Error {
  error: true;
  errorMessage: string;
}

interface ErrorWithMessage2 extends Error {
  error: false;
  errorMessage?: string;
}

type x = ErrorWithMessage | ErrorWithMessage2;

const abc: x = {
  error: false,
};   

if you see abc is type “x” still giving error why ?

How can I keep the character on the screen when I scroll and still have it move along the path?

This is the second time I’m posting this. My previous post was closed without resolving my issue.

This is my question.

Please help me calculate the scrollProgress so that my pathIcon always stays within the screen when scrolling. Or if you have any other ideas, please let me know.

Here is my code :

  pathIcon.style.offsetPath = `path('${Path_440.getAttribute("d")}')`;
      const pathLength = Path_440.getTotalLength();

      function clamp(min, val, max) {
        return Math.min(Math.max(min, val), max);
      }

      function updatePath() {
        const docElt = document.documentElement;
        const pathBox = theFill.getBoundingClientRect();

        // calculates scroll progress based on viewport progress
        const scrollProgress = clamp(
          0,
          -pathBox.y / (pathBox.height - docElt.clientHeight),
          1
        );

        pathIcon.style.offsetDistance = `${scrollProgress * 100}%`;

        // These lines fill in the dashes as you scroll down.
        const drawLength = pathLength * scrollProgress;
        const rest = pathLength - drawLength;
        theFill.style.strokeDasharray = `${drawLength}px ${rest}px`;
      }

      updatePath();
      window.addEventListener("scroll", () => updatePath());
 body {
        height: 500vh;
        background: #f1f1f1;
      }
      .container {
        display: flex;
        justify-content: center;
      }
      #pathIcon {
        position: absolute;
        inset: 0;
        width: 100px;
        height: 100px;
        offset-rotate: 0rad;
      }
      .middlePath {
        position: absolute;
      }
      .crossLine {
        position: absolute;
      }
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <div style="height: 175px"></div>
    <div class="container">
      <div style="position: relative">
        <img
          class="crossLine"
          src="/public/pngegg.png"
          width="580"
          height="1500"
          alt=""
        />
        <svg
          width="540"
          height="2990"
          viewBox="0 0 540 2990"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
          class="middlePath"
        >
          <defs>
            <path
              id="Path_440"
              d="M253.744 2C253.744 2 8.36236 68.4995 17.2435 261C26.1246 453.5 380.243 311.5 380.243 531C380.243 750.5 15.2436 631.5 2.24357 826C-10.7564 1020.5 500.798 1091 535.244 1258.5C569.689 1426 296.243 1473 279.744 1460.5"
              stroke="#F39029"
              stroke-width="4"
            />
          </defs>
          <use href="#Path_440" stroke-dasharray="20 10" />
          <use id="theFill" href="#Path_440" />
        </svg>
        <svg
          id="pathIcon"
          viewBox="0 0 100 191"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
          xmlns:xlink="http://www.w3.org/1999/xlink"
        >
          <rect width="100" height="191" fill="url(#pattern0)" />
          <defs>
            <pattern
              id="pattern0"
              patternContentUnits="objectBoundingBox"
              width="1"
              height="1"
            >
              <use
                xlink:href="#image0_126_965"
                transform="matrix(0.00376726 0 0 0.00197239 -0.00104536 0)"
              />
            </pattern>
            <image
              id="image0_126_965"
              width="266"
              height="507"
              xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUh"
            />
          </defs>
        </svg>
      </div>
    </div>
  </body>
</html>

It looks fine at first glance, but when I scroll, the pathIcon moves too fast and sometimes goes off-screen. I want it to slow down or stay fixed in the middle of the screen but still move to the path. This would make it smoother and give a better overview of the path.

Here is the current state and my desired outcome.
Please help me. Thank you for all your responses

I’ve tried the method mentioned above, but it still doesn’t keep the pathIcon within the screen when scrolling. The pathIcon moves too fast and goes off-screen.

Next.js success build in local but fails on vercel

When I run build on local I get no errors, but in Vercel I get this error:

Error occurred prerendering page "/pt/my-profile".
TypeError: Cannot read properties of undefined (reading '0')

It only happens in this page.tsx:

"use client";
import Text from "@/app/components/Text";
import {
  Button,
  Card,
  CardBody,
  Link,
  Snippet,
  Avatar,
} from "@nextui-org/react";
import { IconPencil, IconTrash } from "@tabler/icons-react";
import { useUserContext } from "@/app/context/UserContext";
import { getCountry } from "@/app/utils/getCountry";
import { useTranslations } from "next-intl";
import PillPalIcon from "./components/PillPalIcon";
import HealthSyncIcon from "./components/HealthSyncIcon";

const MyProfilePage = ({
  params: { locale },
}: {
  params: { locale: string };
}) => {
  const { user } = useUserContext();
  const country = getCountry();
  const t = useTranslations("myProfile");

  const details: string[][] = [
    [
      t("personalInfo.name"),
      t("personalInfo.age"),
      t("personalInfo.gender"),
      t("personalInfo.country"),
      t("personalInfo.language"),
    ],
    [user?.name, user?.age, user?.gender, country, locale],
  ];

  return (
    <main className="min-h-screen flex flex-wrap justify-evenly p-12">
      <section className="flex flex-col [&>*]:p-10 [&>*]:my-4">
        <Card>
          <Text>
            {t("title")}: {user.profileType}
          </Text>
          <CardBody className="flex flex-row items-center">
            <Avatar name={""} size="lg" className="m-2" />
            <div className="[&>*]:m-2 flex flex-col">
              <Button
                radius="full"
                variant="solid"
                color="primary"
                endContent={<IconPencil />}
              >
                {t("btns.change")}
              </Button>
              <Button
                radius="full"
                variant="bordered"
                endContent={<IconTrash />}
              >
                {t("btns.remove")}
              </Button>
            </div>
          </CardBody>
        </Card>
        <Card>
          <Text> {t("personalInfo.title")}</Text>
          <CardBody className="flex flex-row justify-between">
            {details?.map((detail, i) => (
              <div
                key={i}
                style={{
                  fontWeight: i === 0 ? "bold" : "normal",
                }}
                className="flex flex-col font-black [&>*]:m-2"
              >
                {detail?.map((item, j) => (
                  <p key={j}>{item}</p>
                ))}
              </div>
            ))}
          </CardBody>
        </Card>
        <Card>
          <Text>{t("conditions.title")}</Text>
          <CardBody className="[&>*]:m-2">
            {user?.existingHealthCondition &&
              user?.existingHealthCondition.map(
                (condition: string, i: number) => (
                  <Snippet
                    hideCopyButton
                    hideSymbol
                    key={i}
                    className="grid place-content-center"
                  >
                    {condition}
                  </Snippet>
                )
              )}
          </CardBody>
        </Card>
      </section>
      <section className="flex flex-col [&>*]:p-10 [&>*]:my-4">
        <Card>
          <Text>{t("sync.title")}</Text>
          <p>{t("sync.description")}</p>
          <CardBody className="flex flex-row justify-between">
            <div className="flex flex-col [&>*]:m-2">
              <p className="flex items-center [&>*]:mr-2">
                <PillPalIcon />
                PillPal
              </p>
              <p className="flex items-center [&>*]:mr-2">
                <HealthSyncIcon />
                HealthSync
              </p>
            </div>
            <div className="flex flex-col [&>*]:m-2">
              <Link className="text-[#63A87D]">{t("sync.pillpal")}</Link>
              <Link className="text-[#63A87D]">{t("sync.healthsync")}</Link>
            </div>
          </CardBody>
        </Card>
      </section>
    </main>
  );
};

export default MyProfilePage;

Its a profile page with nothing particular, fairly static… It works perfectly in local.
Im using next": "14.0.2"

This is my next.config.json:

const createNextIntlPlugin = require("next-intl/plugin");

const withNextIntl = createNextIntlPlugin();

/** @type {import('next').NextConfig} */

const nextConfig = {
  reactStrictMode: true,
  eslint: {
    ignoreDuringBuilds: true,
  },
  compiler: {},
  images: {
    unoptimized: true,
    remotePatterns: [
      {
        protocol: "https",
        hostname: "d1pe6f90ru47yo.cloudfront.net",
      },
    ],
  },
};

module.exports = withNextIntl(nextConfig);

I’ve tried to downgrade and upgrade some versions many times… But nothing seems to be working. And The only info I get from Vercel is that line TypeError: Cannot read properties of undefined (reading '0') Which is false, because If I Comment all the code of the page I still get the error…
Pls can someone help me?

Consistent “Incomplete response received from application” – NodeJS app on cPanel with Express

I’m working on a NodeJS API. For the sake of clarification, we’ll say my API url is api.mydomain.com. The endpoint that I’m having trouble with is /ts/password. This endpoint’s function is to send a GET request to my Teamspeak3 server webquery to generate a temporary password (using the npm package axios). Everything seems to work as intended when I’m running the API locally on my machine in VS Code, but when I upload it to my hosting provider via cPanel’s built-in NodeJS app module, this /ts/password endpoint returns “Incomplete response received from application”
when a request is sent to it. I have reviewed my code countless times, and can’t seem to find any reason as to why this is happening; but it’s even more confusing how it works on my local machine when the endpoint is called via localhost, but not when called through my domain when hosted on cPanel. I’ve also tried reinstalling node modules, but wasn’t successful there either.

const configFile = require("./config.json")

const express = require("express")
const mysql = require("mysql")
const app = express()
const bodyParser = require("body-parser")
const axios = require("axios")
const panelHeaders = {
    headers: { Authorization: `Bearer ${configFile.panelApiKey}` }
}
const dbConn = mysql.createConnection({
    host: configFile.mdbHost,
    user: configFile.mdbUsername,
    password: configFile.mdbPassword,
    database: configFile.mdbName
})

app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))

const characters ='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

function generateTsPassword(length) {
    let result = '';
    const charactersLength = characters.length;
    for ( let i = 0; i < length; i++ ) {
        result += characters.charAt(Math.floor(Math.random() * charactersLength));
    }

    return result;
}

app.get("/ts/password", (req, res) => {
    const endpoint = "/ts/password"
    if(req.headers.authorization === configFile.apiKey) {
        const tempPw = generateTsPassword(8)
        const url = "http://ts3.operationsrp.com:10080/1/servertemppasswordadd?api-key=" + configFile.ts3ApiKey + "&pw=" + tempPw + "&duration=300&desc=Via+OperationsRP+API"
        axios.get(url)
            .then(function (response) {
                if(response.data.status.code === 0) {
                    res.status(200).send({status: "SUCCESS", statusCode: 200, password: tempPw})
                } else if(response.data.status.code === 1539) {
                    res.status(400).send({status: "BAD_REQUEST", statusCode: 400, message: "An error occurred with the downstream request: required parameter not found. Try again later or contact development."}) // occurrs when a required url query param sent via the teamspeak api url is missing
                }
            })
            .catch(function (error) {
                if(error.response.data.status.code === 7) {
                    res.status(500).send({status: "ERROR", statusCode: 500, message: "An unknown error occurred with the downstream request, and it was cancelled. Try again later or contact development."}) // usually occurrs when the virtual server id is incorrect/not found
                } else if(error.response.data.status.code === 1538) {
                    res.status(404).send({status: "NOT_FOUND", statusCode: 404, message: "An error occurred with the downstream request: invalid command or endpoint. Try again later or contact development."}) // occurrs when the command/endpoint sent via the teamspeak api url is not valid
                } else if(error.response.data.status.code === 5122) {
                    res.status(401).send({status: "UNAUTHORIZED", statusCode: 401, message: "An error occurred with the downstream request: invalid API key. Try again later or contact development."}) // occurrs when the api key sent via the teamspeak api in the url query param is not valid
                } else if(error.response.data.status.code === 5124) {
                    res.status(401).send({status: "UNAUTHORIZED", statusCode: 401, message: "An error occurred with the downstream request: missing API key. Try again later or contact development."}) // occurrs when no api key is supplied in the request to the teamspeak api
                } else {
                    res.status(500).send({status: "ERROR", statusCode: 500, message: "An unknown error occurred with the downstream request. Try again later or contact development."}) // could really be anything
                }
            })
    } else {
        res.status(401).send({status: "UNAUTHORIZED", statusCode: 401, message: "Missing or invalid API key."})
    }
})

Firebase is saying that the ID doesn’t match

I’ve made a website for my school, but I’m trying to expand on it. It’s not that secure with auth and such, so I’m making a server for users to login, then when they want to update their settings on the website, it will send a request to the server to do so.

I’m currently trying to work on the user logging in. When I go to the “/login” route, it brings me to the Google login page. I login and it brings me to the “/app” route. In the console, I get the log below.

FirebaseAuthError: Firebase ID token has incorrect "aud" (audience) claim. Expected "school-progress-g" but got "1090170234957-5ntr48jf178o9befpp5n0603hoh7m2rh.apps.googleusercontent.com". Make sure the ID token comes from the same Firebase project as the service account used to authenticate this SDK. See https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve an ID token.
    at FirebaseTokenVerifier.verifyContent (/rbd/pnpm-volume/124c6272-9622-4f1d-925a-072a4f9e9ad7/node_modules/firebase-admin/lib/auth/token-verifier.js:239:19)
    at /rbd/pnpm-volume/124c6272-9622-4f1d-925a-072a4f9e9ad7/node_modules/firebase-admin/lib/auth/token-verifier.js:160:18 {
  errorInfo: {
    code: 'auth/argument-error',
    message: 'Firebase ID token has incorrect "aud" (audience) claim. Expected "school-progress-g" but got "1090170234957-5ntr48jf178o9befpp5n0603hoh7m2rh.apps.googleusercontent.com". Make sure the ID token comes from the same Firebase project as the service account used to authenticate this SDK. See https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve an ID token.'
  },
  codePrefix: 'auth'
}

I would also appreciate some help with how I would be able to continue developing this login system into my website, after the error is solved. Here are my code files:

server.js

const cookieParser = require("cookie-parser");
const express = require("express");
const admin = require("firebase-admin");

const serviceAccount = require("./serviceAccountKey.json");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://school-progress-g-default-rtdb.firebaseio.com",
});

const PORT = process.env.PORT || 3000;
const app = express();

app.engine("html", require("ejs").renderFile);
app.use(express.static("static"));

app.use(cookieParser());

const firebaseAuthMiddleware = (req, res, next) => {
  const idToken = req.cookies.idToken || "";
  
  if (idToken == "") {
    return next();
  }

  admin
    .auth()
    .verifyIdToken(idToken)
    .then((decodedToken) => {
      req.user = decodedToken;
      next();
    })
    .catch((error) => {
      console.log(error);
      next();
    });
};
app.use(firebaseAuthMiddleware);

const { google } = require("googleapis");

const oauth2Client = new google.auth.OAuth2(
  "1090170234957-5ntr48jf178o9befpp5n0603hoh7m2rh.apps.googleusercontent.com",
  "XXXXXXXX (censored)",
  "https://scpr-server-version.glitch.me/callback"
);

app.get("/login", (req, res) => {
  const authUrl = oauth2Client.generateAuthUrl({
    access_type: "offline",
    scope: ["https://www.googleapis.com/auth/userinfo.email"],
  });
  res.redirect(authUrl);
});

app.get("/callback", async (req, res) => {
  const { tokens } = await oauth2Client.getToken(req.query.code);
  res.cookie("idToken", tokens.id_token);
  res.render("app.html");
  return false;
  res.redirect("/app");
});

app.get("/logout", (req, res) => {
  res.clearCookie("idToken");
  res.redirect("/login");
});

app.get("/app", (req, res) => {
  if (req.user) {
    res.render("app.html");
  } else {
    res.redirect("/login");
  }
});

app.listen(PORT, () => {
  console.log(`Listening on port ${PORT}`);
});

I appreciate any help I can get! <3

I’ve tried changing the client ID in server.js with my Firebase ID, but it just causes more errors.

Can an aborted HTTP fetch from a web browser (abortController abort()) be recognized in a Go backend app (using the Context package)?

I’m having problems troubleshooting why a cancelled request in the frontend isn’t reaching a backend API. In other words, sending a GET/POST request using axios works just fine. But once .abort() kicks in, the network console shows request cancelled, which is also fine, but the backend does not recognized this cancellation.

The frontend code is identical to the following:
https://github.com/axios/axios/issues/4338#issuecomment-1002364900

Unfortunately, according to the backend api logs, the requests goes through as normal. No canceled request or error appears in the backend logs.

On a related note, when a similar request is made from other clients, like using curl in a terminal, or from a desktop app: Postman, the backend picks up the cancellation and the logs show: error: timeout: context canceled

Is it just not possible for javascript’s abort() to be picked up in the backend (Go app using ctx.Done()? Is there something special a CURL request is signaling that an aborted request from the browser isn’t?

Typescript passing whole object vs single key when only single key is needed by React FC

I am contemplating whether I should pass the whole object, vs passing the single required key of the object to my React Functional Component.
I know Typescript passes by reference so there is not any performance impact, but I want to know what is a better practice as far as programming paradigms and best practices are concerned.

The object in question is fairly big, having 11 keys. A couple of keys have objects and array of objects as values.

What I need in my FC is just a key of type string.

How to implement a Nested list with multi-selection

Currently there is the following list implementation:

<select id='optSelect' multiple>
                            
                                <optgroup label='Option1'>
                                    <option value='Option1' style='font-size: 15px;'>Option1</option>
                                    <option value='Option12' style='font-size: 15px;'>Option12</option>
                                    <option value='Option13' style='font-size: 15px;'>Option13</option>
                                </optgroup>
                            
                                <optgroup label='Option2'>
                                    <option value='Option21' style='font-size: 15px;'>Option21</option>
                                    <option value='Option22' style='font-size: 15px;'>Option22</option>
                                    <option value='Option23' style='font-size: 15px;'>Option23</option>
                                </optgroup>
                            
                                <optgroup label='Option3'>
                                    <option value='Option31' style='font-size: 15px;'>Option31</option>
                                    <option value='Option32' style='font-size: 15px;'>Option32</option>
                                    <option value='Option33' style='font-size: 15px;'>Option33</option>
                                </optgroup>
                           
                        </select>
                

It is necessary to implement it so that when hovering over, for example, the Option2 element on the right at the Option2 level, a list of elements with:

<option value='Option21' style='font-size: 15px;'>Option21</option>
                                    <option value='Option22' style='font-size: 15px;'>Option22</option>
                                    <option value='Option23' style='font-size: 15px;'>Option23</option>

How to implement it? Help please!

JavaScript in Bootstrap 5

I’m quiet new to building webpages and just started building one with Bootstrap 5.
I want to add/remove the bootstrap class “bg-opacity” to my navbar based on viewport width and thought I can do so with JS. But the function I found is not working, cause BS doesn’t use JQuery anymore. Is there an easy way to add/remove classes that exist in Bootstrap 5?

I would be very happy about an answer.

Cheers and thanks in advance 🙂

I tried to use this function


jQuery(document).ready(function($) {
    var alterClass = function() {
      var ww = document.body.clientWidth;
      if (ww < 767) {
        $('.navbar').addClass('bg-opacity-75');
      } else if (ww >= 768) {
        $('.navbar').removeClass('bg-opacity-75');
      };
    };
    $(window).resize(function(){
      alterClass();
    });
    //Fire it when the page first loads:
    alterClass();
  });

Child routes not working with Remix 2.8.1

Repo: https://github.com/leongaban/remix-tutorial

I’m using a brand new build of Remix.

My vite.config.ts:

import { vitePlugin as remix } from '@remix-run/dev';
import { installGlobals } from '@remix-run/node';
import { defineConfig } from 'vite';
import tsconfigPaths from 'vite-tsconfig-paths';

installGlobals();

export default defineConfig({
  plugins: [
    remix({
      ignoredRouteFiles: ['**/.*'], // <-- default without this did not work too
    }),
    tsconfigPaths(),
  ],
});

Settings component:

import { Link, Outlet } from '@remix-run/react';

export default function Settings() {
  return (
    <div>
      <h1>Settings</h1>
      <p>This is the Settings page</p>
      <nav>
        <Link to="app">App</Link>
        <br />
        <Link to="profile">Profile</Link>
        <Outlet />
      </nav>
    </div>
  );
}

settings/app component:

import { Link } from '@remix-run/react';

export default function App() {
  return (
    <div>
      <h1>App Settings</h1>
      <p>...</p>
    </div>
  );
}

Folder structure:
enter image description here

The Bug

I navigated to /settings and click on the App Link

I get a 404 Not Found Error and the following error in the Chrome console:

“Error: No route matches URL “/settings/app””

Node.js: ffmpeg command not waiting for other ffmpeg command promise to be resolved

I am trying to node.js program, in which fluent-ffmpeg first converts an input-mp4-file to an mp3 file and after that fluent-ffmpeg command should trim the mp3 file (for example only 0:12 – 0:48).
I am using promises for that but it seems like that the trimFile() method is not waiting for the promise to be resolved. I have the following code:

// data = [stream, duration, trimStartTime, res, name]
async function convertMP4ToMP3(data) {
    var name = data[4];
    let inputFilePath = `./temp/${name}.mp3`
    return new Promise((resolve, reject) => {
        ffmpeg()
            .input(`./temp/${name}.mp4`)
            .output(`./temp/${name}.mp3`)
            .audioCodec('libmp3lame')
            .on('error', reject)
            .run();
        console.log("convertMP4toMP3 DONE!n");
        resolve(data.concat([inputFilePath]));
    });
}

// data = [stream, duration, trimStartTime, res, name, inputFilePath]
async function trimFile(data) {
        console.log("trimming starting");
  return new Promise((resolve, reject) => {
      setTimeout(() => {
    let duration = data[1];
    if (duration > 0) {
    let trimStartTime = data[2];
    let inputFilePath = data[5];

    var dotIndex = inputFilePath.lastIndexOf(".");
    var outputFilePath = inputFilePath.substring(0, dotIndex) + "_t" + inputFilePath.substring(dotIndex);
   
    const trim = new ffmpeg({source: inputFilePath});
    trim
        .setStartTime(trimStartTime)
        .setDuration(duration)
        .on("start", function(commandLine) {
            console.log("Spawned ffmpeg with: " + commandLine)
        })
        .on('end', function(err) {
                if (!err) {
                    console.log('trimming Done');
                }
            })
        .on('error', function(err) {
                console.log('error in trimFile(): ', err);
            })
        .saveToFile(outputFilePath);
   
    }        
    resolve(data);
    }, "100");  // explanation underneath
    });
}

If I execute the following code:

func1(data)
        .then(func2)
        .then(convertMP4ToMP3)
        .then(trimFile)

The trimfile() method says: Invalid argument. If I change the timeout to 6000 instead of 100. It works. I was spectating the files in the filesystem and saw, that convert sometimes is not done before trimFile is executed. Can someone explain, why the trimFile() is not waiting for the resolve()?

I also tried:

// data = [stream, duration, trimStartTime, res, name]
async function convertMP4ToMP3(data) {
    var name = data[4];
    let inputFilePath = `./temp/${name}.mp3`
    return new Promise((resolve, reject) => {
        ffmpeg()
            .input(`./temp/${name}.mp4`)
            .output(`./temp/${name}.mp3`)
            .audioCodec('libmp3lame')
            .on('error', reject)
            .on('end', resolve)
            .run();
        console.log("convertMP4toMP3 DONE!n");
    });
}

But first this doesnt work neither and second thus I can not pass the string inputFilePath to the trimfile() method (because .on(‘end’, resolve(data.concat([inputFilePath]))) does not work for me).

I want to cache cloud function data in to cdn. Whatever i tried is caching in browser only

I have a webpage application developed using Flutter.
I am hosting this on Firebase hosting.
There are some data which changes over a long period of time say in 2-3 days. So I am fetching this data through Firebase cloud function.

Is there any way the data sent by the cloud function get cached to cdn? The steps that i tried so far, are caching in the browser only.

Here is firebase.json

{
  "hosting": {
    "target": "flutter",
    "public": "build/web",
    "headers": [
      {
        "source": "**",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "'public, max-age=300, s-maxage=600'"
          }
        ]
      }
    ],
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      },
      {
        "source": "/fetchData/**",
        "destination": "/index.html"
      }
    ]
  }
}

and here is my cloud function

var globalData = "some global static data"
const functions = require("firebase-functions");

const cors = require("cors");

exports.fetchData = functions.https.onRequest(async (req, res) => {
  var corsFn = cors();

  await corsFn(req, res, async function () {
    var body = req.body;


    res.set("Cache-Control", "public, max-age=300, s-maxage=600");

    res.status(201).send({
      data: globalData,
    });
  });
});

with this, I am able to cache the cloud function data but only in the browser. What I want is to cache in Firebase global cdn.