document.execCommand and document.queryCommandState doesn’t work in Svelte

I want to create a text editor, but there are some confusing problems that have come up :

  • The text formatting doesn’t work unless text is selected first
  • The color change on the buttons when the formatting is active sometimes works and sometimes doesn’t. I’ve tried three methods : wrapping it in a function didn’t work, adding an arrow function () => in the onClick makes the color appear active even before I click, and when I do click, it doesn’t change. Using document.queryCommandState directly without wrapping in a function didn’t work either.

And is using bind:innerHTML as I did safe for security? If it’s not safe, what is the safe way?

<script>
    function formatText(command){
        document.execCommand(command, false, null);
    }
    
    function isFormatActive(command){
        return document.queryCommandState(command);
    }
</script>

<div class="bg-black text-white font-lg font-bold">
    <button class:bg-emerald-950={isFormatActive("italic")} on:click={() => formatText("italic")} class="p-4">
        <i>I</i>
    </button>
    <button class:bg-emerald-950={() => isFormatActive('bold')} on:click={() => formatText('bold')} class="p-4">
        <b>B</b>
    </button>
    <button class:bg-emerald-950={document.queryCommandState('underline')} on:click={() => formatText('underline')} class="p-4">
        <u>U</u>
    </button>
</div>
<div class="bg-emerald-500 text-white p-4 rounded-lg focus:border-none focus:outline-none" contenteditable="true">hello</div>

state variables returns undefined

I need help with managing react states, I can’t seem to wrap my head around it.

I have a component that receives the id of a database entry from another page via useLocation, I then use that id with an axios get request to pull the rest of the data into an array. However, when I am trying to use the data from the get request as a defaultValue for an MUI TextField it doesn’t render the data naturally, the states returns as undefined after the page loads. I have to set the TextField’s key to the get request data (a work around I found in the web) to render. Then when I try to submit the form, the value from the Textfield displays as undefined though the Texfield contains the data from the get request.

const location = useLocation();
const [info, setInfo] = useState([]);

useEffect(()=>{
  axios
    .get("//localhost:3001/Info/" + location.state.id)
    .then((response)=>{
      setInfo(response.data);
  })
});

const validationSchema = Yup.object().shape({});

const formik = useFormik({
  initialValues: {
    name: info.name
  },
  validationSchema: validationSchema,
  onSubmit: (values) => {
    console.log(values) // displays {name: undefined, .....}
  }
});

return(
  <>
    <Container>
      <form onSubmit = {formik.handeSubmit}>
        <TextField
          id = "name"
          label = "Name"
          name = "name"
          onChange = {formik.handleChange}
          onBlur = {formik.handleBlur}
          key = {info.name} //Textfield blank without setting key
          defaultValue = {info.name}
        />
        <Button type = "Submit"> Submit </Button>
      </form>
    </Container>
  </>
);

I am expecting the TextFields default values to render correctly without declaring a key as a work around. Also, I expect the values of the textfields to contain the initialvalues from the formik declaration on submit.

Ensure that Promise has been resolved before rendering view

What specific syntax needs to be changed in the code below in order for the value returned by the currentSession() function to correctly set the html that is rendered to the user in the web browser?

Specifically, what needs to be changed so that the console.log("other groups is: ", groups); line returns a valid array of groups, and so that the logic in the {isGroupOne ? <p>Welcome back!</p> : <p>Please log in.</p>} line is able to execute with isGroupOne having been returned as True?

USE CASE:

A React component needs to render different content for users that are in different user groups. The groups for a given user are indeed returned from a backend service.

PROBLEM:

The problem is that the React component is printing out the user’s groups as a pending promise instead of as a valid array of group names that can be transformed into a Boolean to indicate whether or not the user is in a specific group.

As a result, the wrong content is being printed to the web browser in the example broken code below. Currently, Please log in. is being printed in the browser, even though you can see from the logs below that the promise eventually resolves to give isGroupOne the value of true.

MINIMAL CODE TO REPRODUCE PROBLEM:

Here is the minimal code required to reproduce the problem:

import { fetchAuthSession } from 'aws-amplify/auth';

function Index() {
  let isGroupOne = false;

  async function currentSession() {
    try {
      const { accessToken, idToken } = (await fetchAuthSession()).tokens ?? {};
      const groups = accessToken["payload"]["cognito:groups"]
      console.log("these groups: ", groups);
      return groups;
    } catch (err) {
      console.log(err);
    }
  }

  const groups = currentSession().then(groups => {
    console.log("those groups is: ", groups);
    //iterate groups array to see if "GroupOne" is in the array
    groups.forEach(group => {
      if (group === "GroupOne") {
        console.log("User is in GroupOne group");
        isGroupOne = true;
        console.log("isGroupOne: ", isGroupOne);
      }
    });

  });
  console.log("other groups is: ", groups);

  return (
    <div>
        {isGroupOne ? <p>Welcome back!</p> : <p>Please log in.</p>}
    </div>

  );
}

export default Index;

LOGS ILLUSTRATING THE PROBLEM:

The following is printed to the console when the page defined by the above minimal code is rendered in the web browser:

other groups is:  Promise {<pending>}
index.js:29 other groups is:  Promise {<pending>}
index.js:10 these groups:  ['GroupOne']
index.js:18 those groups is:  ['GroupOne']
index.js:22 User is in GroupOne group
index.js:24 isGroupOne:  true
index.js:10 these groups:  ['GroupOne']
index.js:18 those groups is:  ['GroupOne']
index.js:22 User is in GroupOne group
index.js:24 isGroupOne:  true

Google Apps Script Web App: Unable to Load HTML Pages Based on URL Parameters

I am experiencing an issue with a Google Apps Script web app I developed. Despite following standard procedures, the app fails to load specific HTML pages based on URL query parameters. Here are the details:
Issue Description
Problem: The web app does not navigate to different pages (such as ‘index’, ’employee’, ‘admin’) based on the URL query parameter page. The URL does not change, and I receive an error message instead of the expected content.
Error Message: “Sorry, unable to open the file at this time. Please check the address and try again.
Steps Taken
Project Setup:

The project includes index, employee, and admin HTML files, referenced without the .html extension in the code.
A doGet function handles URL query parameters to determine which HTML file to serve:

Testing and Debugging:
Verified that file names are correct and match the references in the code.
Checked browser cache and tested in incognito mode to rule out caching issues.
Ensured proper deployment and public access settings.
Monitored network requests and console logs for errors.
Issue Persistence:
The problem persists with minimal HTML content and correct setup.
URLs used include parameters like ?page=admin, but the app does not navigate to the correct page.
Additional Context
Deployment URL: [Your Deployment URL]
Attempts: Multiple re-deployments, browser tests, and code simplifications have been tried without success.
Request
Could you please assist in diagnosing the issue? Are there any known issues with handling URL parameters in Google Apps Script web apps or potential configurations I might be missing? Any guidance or additional steps to resolve this would be greatly appreciated.

Thank you for your assistance.

Proper way to remove a Vue component

What is the correct way to remove Vue child component? I found two ways of doing it.

  1. Emit an event from child component to parent component and parent can remove the child component.
  2. Use v-if inside child component and child component can toggle the condition.

I am more leaning toward the second approach since we don’t have to force parent components to implement listener when it uses this child component. e.g: if this child component is used at 100 places, all those places have to listen for the child custom close event.

Can anyone explain what happen under the hood for both scenario? Is there a different way to remove it? Thanks.

Repl for this example: vue playground

Parent component

<script setup>
import { ref } from 'vue';
import DialogBasic from './DialogBasic.vue';

const isDialogShown = ref(true);
const closeChildDialog = () => isDialogShown.value = false;

</script>

<template>
  <div>
    <h1>Parent Component </h1>
    <DialogBasic
      v-if="isDialogShown"
      @parentCloseDialog="closeChildDialog"
    />
  </div>
</template>

Child component

<script setup>
import { ref } from 'vue';
const isShown = ref(true);
const closeMyself = () => isShown.value = false;

</script>

<template>
  <div v-if="isShown" class="dialog">
    <h1>Dialog Component</h1>
    <button @click="$emit('parentCloseDialog')">Parent closes dialog</button>
    <button @click="closeMyself">Dialog closes itself</button>
  </div>
</template>

<style scoped>
.dialog {
  background-color: aliceblue;
  outline: solid red 1px;
  row-gap: 5px;;
  width: 300px;
  display: flex;
  flex-direction: column;
}
</style>

Javascript/CSS Display styling won’t change

const hamburgerMenuBtn = document.getElementById("hamburger-menu-button");

hamburgerMenuBtn.addEventListener("click", function() {
  hamburgerPopupToggle()
});

function hamburgerPopupToggle() {
  console.log("Button pressed");
  const hamburgerMenuPopup = document.getElementById("hamburger-menu-popup");
  if (hamburgerMenuPopup.style.display === "block") {
    hamburgerMenuPopup.style.display = "none";
    console.log(hamburgerMenuPopup.style.display);
  } else {
    hamburgerMenuPopup.style.display = "block";
    console.log(hamburgerMenuPopup.style.display);
  }
}
#hamburger-menu-popup { display: none; }
<div class="hamburger-menu">
  <span id="hamburger-menu-button">menu</span>
  <div id="hamburger-menu-popup">
    <div id="home-button">Home</div>
    <div id="create-post">Create a Post</div>
  </div>
</div>

The popup opens
(https://i.sstatic.net/4hlVl4VL.png)
But then instead of setting display style back to “none”, it sets it to “unset !important”, BUT it logs that it’s “none” (https://i.sstatic.net/DadeuwQ4.png)(https://i.sstatic.net/bmL9RzHU.png)

So, for some reason it logs what was supposed to happen, but the CSS doesn’t change whatsoever. (It changes, but not as expected)

Using Redux-Toolkit slice action with class components via connect HOC, does it require dispatch or not?

I have been working on an older code base with class components using Redux connect HOC. There are few RTK slices introduced before. I am abit confused as to why these 2 ways of using the action from the slice is working correctly (can see in Redux Toolkit that ways update the state and appear in the Actions panel (left hand side).

2 ways:

  1. with dispatch (updateAbc)
  2. without dispatch (updateXyz)

See example below

const mapDispatchToProps = (dispatch) => {
    return {
        updateAbc: (params) => dispatch(updateAbc(params)),
        updateXyz,
    }
}

Both are from the slice file:

const sampleSlice = createSlice({
   name: 'sample',
   initialState: {},
   reducers: {
      updateAbc: () => { /* do something */},
      updateXyz: () => { /* do something */}
   }
})
const { actions, reducer } = sampleSlice
export const {
    updateAbc,
    updateXyz,
} = actions

enter image description here

How come both are working or am I missing something or they are just both valid ways (but I don’t see how it dispatches it without the explicit call to dispatch)?

Why does canvas.toDataURL() and canvas.toBlob() produce corrupt images on Firefox?

On Chrome and Safari, I am not having problem generating a snapshot image of a video. However, I’ve been for hours trying several different things on Firefox, but the image always comes corrupted, with a “random color” each time.

Example minimal code – https://jsfiddle.net/4uy8j1bf/1/

Basically, I’m loading a video file into a <video element, and then draw it on a <canvas>, and from there, generate either a data URL or blob URL.

But, while Chrome and Safari have no problem getting the canvas image, Firefox always gives corrupt images, even if I seek / change the video time (any video).

The canvas image is drawn fine. It’s the generation of data/blob URL that doesn’t seem to work.

Do you know why? What can I do to get this working on Firefox?

Firefox:

Firefox - Canvas and Blob URL

Chrome:

Chrome - Canvas and Blob URL

The example code:

var _CANVAS = document.querySelector("#video-canvas");
var _CTX = _CANVAS.getContext("2d");
var _VIDEO = document.querySelector("#main-video");

$("#file").on('change', function() {

    // Object Url as the video source
    $("#main-video").attr('src', URL.createObjectURL($("#file")[0].files[0]));

    // Load the video and show it
    _VIDEO.load();
        _VIDEO.currentTime = 0;
        _VIDEO.play();

    // Load metadata of the video to get video duration and dimensions
    _VIDEO.addEventListener('loadedmetadata', function() {
        // Set canvas dimensions same as video dimensions
        _CANVAS.width = _VIDEO.videoWidth;
        _CANVAS.height = _VIDEO.videoHeight;
    });

    _VIDEO.addEventListener('canplay', function() {
        _CANVAS.style.display = 'inline';
        _CTX.drawImage(_VIDEO, 0, 0, _VIDEO.videoWidth, _VIDEO.videoHeight);
        
        // var dataUrl = _CANVAS.toDataURL('image/jpeg', 0.7);
        // $('body').append('<img src="'+dataUrl+'" />');
        
        _CANVAS.toBlob(blob => {
            if (blob) {
                const dataUrl = URL.createObjectURL(blob);
                $('body').append('<img src="'+dataUrl+'" />')
            } else {
                console.log('Error creating blob from canvas');
            }
        }, 'image/png');
    });
});

Is there a way to submit a form with multiple copies of the same fields (or component) in an organized way?

I’ve got the following component:

<script>
    export let componentID;

    console.log("component iD", componentID)
</script>

<div>
    <div class="grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
        <div class="sm:col-span-3">
            <label class="label">
                <span class="label-text text-lg">Title</span>
            </label>
            <input type="text" name="track-title[][{componentID}]" class="input input-bordered input-lg w-full">
        </div>

        <div class="sm:col-span-1">
            <label class="label">
                <span class="label-text text-lg">Duration</span>
            </label>
            <input type="text" name="track-duration[][{componentID}]" class="input input-bordered input-lg w-full">
        </div>
    </div>
</div>

As you can see, this component contains only 2 input fields. I have the following route (+page.svelte) and what I want to do is to have multiple copies of the same component, something like this:

<script>
    import TrackForm from "../../components/forms/TrackForm.svelte";

</script>

<form method="POST">
    <TrackForm componentID="1" />

    <br/>
    <hr>
    <br/>
    <TrackForm componentID="2" />

    <button type="submit" class="btn-primary btn-wide btn-info mt-10">Save</button>
</form>

Eventually, the components will be added dynamically using a button, for now, this is a proof of concept.

The action in +page.server.js is not doing anything at the moment, just printing the submitted data:

export const actions = {
    default: async ({ request }) => {
        const data = Object.fromEntries(await request.formData());
        console.log("data:", data);

        return {}
    }
}

When submitting the form I’m getting the following:

data: {
  'track-title[][1]': 'aaaaa',
  'track-duration[][1]': '111',
  'track-title[][2]': 'vbbb',
  'track-duration[][2]': '2222'
}

What I’m wondering is whether there’s a way to automatically get the data in a better format, say:

[
   {
     "track-title": 'aaaaa',
     "track-duration": '111'
   },
   {
     "track-title": 'vbbb',
     "track-duration": '2222'
   }
]

or a library that does that.

react router not fetching data unless i reload

my idea is to set a login functionality where users could login and when submitting data the user would be redirected to home page, then his profile would show instead of login in the top corner, the problem seem that when i login and navigate to the home page and click on the profile, no data would be there unless i reload

in my server there is no data sent through the fetchToken function unless i reload even though i put loader to my page.

my submit function where i send data to backend and get back a token

async function handleSubmit(e: SyntheticEvent) {
    e.preventDefault();
    setSubmitting(true);
    // if no file selected set empty string to show error and don't send data
    if (!fileName) {
      setFileName("");
      setSubmitting(false);
      return;
    }
    const target = e.target as HTMLFormElement;
    const formData = new FormData(target);
    const response = await fetchLogin(formData);

    if (response.token) {
      localStorage.setItem("token", response.token);
      setSubmitting(false);
      
      navigate("..");
    } else {
      setError(response);
      setSubmitting(false);
    }
  }

my fetchLogin function

export async function fetchLogin(data: FormData) {
  try {
    const response = await fetch(`${URL}/onlineUsers/login`, {
      method: "POST",
      body: data,
    });
    const resData = await response.json()
    console.log(resData);
    
    return resData
  } catch (error) {
    // returns the error message if it exist
    return processError(error);
  }
}

my loader and login page

const LoginPage = () => {
  const data = useLoaderData() || {name:"",imageUrl:""}

   
  return (
    <div>
      <From  data={data as LoggedUserData}/>
    </div>
  );
};


export async function loginLoader() {
    const resData = await fetchToken()
    if(resData)return resData
    return;
}

my fetchToken function

export async function fetchToken(){
  const response = await fetch(`${URL}/onlineUsers/token`,{
    method:"POST",
    headers:{
      'Authorization':`Bearer ${token}`
    }
  })
  const resData = await response.json();
  return resData
}

in my backend, a fetch is sent but not with my token, what seems to be the problem? do i need to put my fetching function in redux state (thunk) ?

When trying to display fetched API data in react it isnt read, or i get an undefined error for the data

I am trying to display data of basketball players through a API fetch request in React. The API has data I can access such as firstname, lastname, teamname, teamlogo, and so on… I have the fetch request set up in my main App.jsx page and i then feed a prop i also have on App.jsx from my useState const named ‘players’, to the rendered cards page where i have simple cards logic to render the information of different players on each card. The issue is that i either get no errors and no displayed data from the API, or an error as follows for the first data property.

MultiplePlayerCards.jsx:59 Uncaught TypeError: Cannot read properties of undefined (reading ‘firstname’)

for clarity this is my App.jsx:

import { useState, useEffect } from "react";
import MultiplePlayerCards from "./components/MultiplePlayerCards";
import PlayerCard from "./components/PlayerCard";
import "./App.css";

const App = () => {
  const [players, setPlayers] = useState([]);

  useEffect(() => {
    const fetchMyEvents = async () => {
      try {
        const response = await fetch(
          "https://api-nba-v1.p.rapidapi.com/players/statistics?game=8133",
          {
            method: "GET",
            headers: {
              "x-rapidapi-key": "123456789",
              "x-rapidapi-host": "api-nba-v1.p.rapida pi.com",
            },
          },
        );

        if (response.ok) {
          const data = await response.json();
          setPlayers([data]);
        } else {
          throw new Error("Failed to fetch players");
        }
      } catch (error) {
        console.error("Error fetching players:", error);
      }
    };

    fetchMyEvents();
  }, []);

  return (
    <>
      <MultiplePlayerCards players={players} />
    </>
  );
};
export default App;

and the file where i have the mapping for each data property i want to display from the players, which is also fed into another card component, which i have for other purposes mainly animations.

import React from "react";
import { useState, useEffect } from "react";
import "./styles.css";
import PlayerCard from "./PlayerCard";
import { playerImages } from "../../player-images";

const MultiplePlayerCards = () => {
  return (
    <div className="app">
      <h1>NBA Player Stats</h1>
      <div className="car-container">
        {players && players.length > 0 ? (
          players.map((player, index) => (
            <PlayerCard
              key={index}
              firstName={player.player.firstname}
              lastName={player.player.lastName}
              fullName={`${firstName} ${lastName}`}
              teamName={player.player.teamName}
              teamLogo={player.player.teamLogo}
              points={player.player.points}
              assists={player.player.assists}
              rebounds={player.player.totReb}
              minutes={player.player.min}
              playerImage={playerImages[fullName]}
            />
          ))
        ) : (
          <p>No players found</p>
        )}
      </div>
    </div>
  );
};

export default MultiplePlayerCards;

so far I have tried to access firstname differently, with just player.firstname instead of player.player.firstname as this was the way i accessed it in a previous project where i just used vanilla JS, but still nothing worked.

returning the sums of the withdraws in bank accounts

I’m working on an exercise where I’m only allowed to use ‘for-loops’ for iterating through the material given. in this case bank accounts and return the sums of the widrawals in a new array, but if the account lacks withdrawals then have it return ‘0’

I’ve figured out how to return the sums of the bank accounts with withdraws I’m struggling trying to figure out how to return ‘0’ for the accounts with not withdraws the desired output should look like this
([300.68,0,5900,0,100]) but my function keeps returning this ([300.68,,5900,,100])
how can I make sure that any account without a “withdrawal” returns a 0?

this is what I Have so far

const bankAccounts = [
  {
    id: 1,
    name: "Susan",
    balance: 100.32,
    deposits: [150, 30, 221],
    withdrawals: [110, 70.68, 120],
  },
  { id: 2, name: "Morgan", balance: 1100.0, deposits: [1100] },
  {
    id: 3,
    name: "Joshua",
    balance: 18456.57,
    deposits: [4000, 5000, 6000, 9200, 256.57],
    withdrawals: [1500, 1400, 1500, 1500],
  },
  { id: 4, name: "Candy", balance: 0.0 },
  { id: 5, name: "Phil", balance: 18, deposits: [100, 18], withdrawals: [100] },
];



function itsSomething(array){
  let newArray = [];
  let total = [];
  for (let i = 0; i < array.length; i++){
  let numbs = array[i].withdrawals
   newArray.push(numbs||0 )
   let sum =0
   for (let x =0; x < newArray[i].length; x++){
  sum+=newArray[i][x]
  total[i]= sum
   
 }
 }



  return total
}


console.log(itsSomething(bankAccounts))

Why is newTabBrowser.contentDocument null?

Running the example code from the Firefox docs page about the Browser console.

https://firefox-source-docs.mozilla.org/devtools-user/browser_console/index.html

var newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
newTabBrowser.addEventListener("load", function() {
 newTabBrowser.contentDocument.body.innerHTML = "<h1>this page has been eaten</h1>";
}, true);
newTabBrowser.contentDocument.location.href = "https://mozilla.org/";

Running it gives me the following error.

Uncaught TypeError: newTabBrowser.contentDocument is null
    <anonymous> debugger eval code:5
    getEvalResult resource://devtools/server/actors/webconsole/eval-with-debugger.js:306
    evalWithDebugger resource://devtools/server/actors/webconsole/eval-with-debugger.js:218
    evaluateJS resource://devtools/server/actors/webconsole.js:953
    evaluateJSAsync resource://devtools/server/actors/webconsole.js:846
    makeInfallible resource://devtools/shared/ThreadSafeDevToolsUtils.js:103
debugger eval code:5:1
    <anonymous> debugger eval code:5

Why is the contentDocument null?

I tried running the above code. According to the docs, “It adds a listener to the currently selected tab’s load event that will eat the new page, then loads a new page.” Instead it generates an Uncaught TypeError: newTabBrowser.contentDocument is null.

Is this right way to solve Two Crystal Balls problem?

I had lecture about this problem and as I understand, I have to find the lowest point from which this ball will break. I thought of using binary search to get O(logN) time complexity. If the ball breaks on the index and breaks again on the index – 1, we simply continue the search until we find an index where it breaks and the one to the left does not.

function two_crystals(data : boolean[]) : number {
  let first_index = 0;
  let last_index = data.length - 1;

  while(first_index <= last_index){
    let mid_index = Math.floor((last_index + first_index) / 2);

    if (data[mid_index]) {
      // Check if it doesn't break at the previous floor
      if (mid_index === 0 || !data[mid_index - 1]) {
        return mid_index;
      }
      // Continue searching in the lower half
      last_index = mid_index - 1;
    } else {
      // Continue searching in the upper half
      first_index = mid_index + 1;
    }
  
  }
  
  return -1
}

Maybe I didn’t understand the problem correctly, but I think this option is better