Having trouble with centering a div in my Vue project with CSS

My code for some reason doesn’t center containers/text properly but instead centers them vertically, but not horizontally.

Instead of horizontally centered text will take up space on the left of the center (image attached)

Would appreciate any help and if I am making some dumb mistake please do let me know

the problem

Here is the code attached
(Dashboard)

<!-- src/views/Dashboard.vue -->

<script setup>
import Navbar from '@/components/TheNavbar.vue';
</script>

<template>
  <div>
    <Navbar />
    <div class="container">
      <div class="title">Welcome to the Dashboard!</div>
    </div>
  </div>
</template>

<style scoped>

.title {
  font-size: 40px;
  font-weight: 600;
}

.container {
  display: flex;
  justify-content: center;
  align-items: center;
}

</style>

(index.js for router)

import { createRouter, createWebHistory } from 'vue-router'
import LandingPage from '../views/LandingPage.vue'
import LoginSignup from '../views/LoginSignup.vue'
import DashboardPage from '../views/DashboardPage.vue'
import BudgetPage from '../views/BudgetPage.vue'
import AnalyticsPage from '../views/AnalyticsPage.vue'
import AccountPage from '../views/AccountPage.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'Landing',
      component: LandingPage,
    },

    {
      path: '/loginsignup',
      name: 'LoginSignup',
      component: LoginSignup,
    },

    {
      path: '/dashboard',
      name: 'Dashboard',
      component: DashboardPage,
    },

    {
      path: '/budget',
      name: 'Budget',
      component: BudgetPage,
    },

    {
      path: '/analytics',
      name: 'Analytics',
      component: AnalyticsPage,
    },

    {
      path: '/account',
      name: 'Account',
      component: AccountPage,
    }
  ],
})

export default router

(App.vue)

<!-- src/App.vue -->

<script setup>
import { RouterLink, RouterView } from 'vue-router'
</script>

<template>
  <main>
      <RouterView />
  </main>
</template>


<style scoped>



</style>

(main.js)

import './assets/main.css'

import { createApp } from 'vue'
import { createPinia } from 'pinia'

import App from './App.vue'
import router from './router'

const app = createApp(App)

app.use(createPinia())
app.use(router)

app.mount('#app')

(index.html)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>EZ Budget</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@iconscout/[email protected]/css/line.css">
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
  </body>
</html>

(main.css)

@import './base.css';

#app {
  max-width: 1280px;
  margin: 0 auto;
  padding: 2rem;
  font-weight: normal;
}

a,
.green {
  text-decoration: none;
  color: hsla(160, 100%, 37%, 1);
  transition: 0.4s;
  padding: 3px;
}

@media (hover: hover) {
  a:hover {
    background-color: hsla(160, 100%, 37%, 0.2);
  }
}

@media (min-width: 1024px) {
  body {
    display: flex;
    place-items: center;
  }

  #app {
    display: grid;
    grid-template-columns: 1fr 1fr;
    padding: 0 2rem;
  }
}

Here is what my project structure looks like

files

Thanks in advance for any help 🙂

Qualtrics custom JS Custom works in question preview but not actual survey

I believe this is a somewhat common issue however I was unable to find a solution. I made a freeform drag-and-drop question on Qualtrics using the custom JS, which works just fine when I preview the question but does not work if I preview the block, preview the block, or take the survey. The JS portion of the code and some log statements are below, and I would appreciate it if anyone has any insight on how I could make it work!

Qualtrics.SurveyEngine.addOnload(function () {
    const draggableIcons = document.querySelectorAll('#breakfast, #dinner');


        draggableIcons.forEach(icon => {
            let isDragging = false;
            let offsetX, offsetY;

            icon.style.position = 'absolute';
            icon.style.zIndex = '1000';

            // Start dragging
            icon.addEventListener("mousedown", (event) => {
                isDragging = true;
                offsetX = event.clientX - icon.getBoundingClientRect().left;
                offsetY = event.clientY - icon.getBoundingClientRect().top;
                icon.style.cursor = "grabbing";  // Change cursor on drag
                event.preventDefault();

                document.addEventListener("mousemove", onMouseMove);
                document.addEventListener("mouseup", onMouseUp);
            });

            // Handle dragging
            function onMouseMove(event) {
                if (isDragging) {
                    icon.style.left = `${event.clientX - offsetX}px`;
                    icon.style.top = `${event.clientY - offsetY}px`;
                }
            }

            // Stop dragging and reset cursor
            function onMouseUp() {
                isDragging = false;
                icon.style.cursor = "grab";  // Reset cursor
                document.removeEventListener("mousemove", onMouseMove);
                document.removeEventListener("mouseup", onMouseUp);
            }
        });

});

I tried out some console.log statements, and when I am on ‘question preview’ I get the correct logs (e.g., “breakfast is being dragged to: (248.333px, 244.333px), Stop dragging breakfast at final position: (248.333px, 244.333px)”). So I can both drag, and see that the items are being loaded/the correct names and positions are being logged. When I am taking the survey or using ‘preview block’, the logs are suggesting that the items and the coordinates aren’t loading (e.g., “ is being dragged to: (, ), Stop dragging at final position: (, )”). Using addOnload or addOnready didn’t make a difference and I cannot seem to figure out what is causing the issue here!

I tried to create a freeform drag and drop question, I was expecting it to work as it does when I preview the question, but it stops working during the actual survey.

Javascript class to sort HTML tables. Unsort method not working [closed]

My class sorts a table alphabetically by the name of the name of the employees and also by the time worked. The problem that I have is that I can make it to “unsort” the table (sort it to the original state) after clicking the name or worked time headings. I thought it would be simple but no I can’t figure it out.

Sorry if it is bad code. I am learning and I basically wrote the class without knowing too much JS.

Thank you!

export { SortingTable };

class SortingTable {
    #data = null;
    #sortedData = null;
    #sortedTimeData = null;
    #originalData = null;

    constructor(table, selector) {
        this.table = table;
        this.selector = selector;
    }


    #getBodyData() {
        const body = this.table;
        const rows = body.getElementsByTagName('tr');
        const data = [];
        const originalData = [];
        
        for (let i = 0; i < rows.length; i++) {
            data.push(rows[i]); // Push the actual row
            originalData.push(rows[i].cloneNode(true)); // Push a deep copy of the row
        }
        
        this.data = data;
        this.originalData = originalData;
    }
    

    #removeBody(){
        const body = this.table.getElementsByTagName('tbody')[0]
        while (body.childElementCount){
            body.removeChild(body.firstElementChild)
        }
    }

    #sortAlphaData() {
        this.data.sort((a, b) => {
            const elementA = a.querySelector(this.selector);
            const elementB = b.querySelector(this.selector);
    
            const nameA = elementA ? elementA.innerText : '';
            const nameB = elementB ? elementB.innerText : '';
    
            return nameA.localeCompare(nameB);
        });
        this.sortedData = this.data;
    }
    
    #sortTimeData(){
        const data = this.data
        const seconds = []
        const newData = []
        for (let i = 0; i < data.length; i++){
            let wholeTime = data[i].querySelector('#workedTime')?.innerText ?? '';
            // console.log(wholeTime)
            const splitTime = wholeTime.split(':')
            const totalSeconds = (parseFloat(splitTime[0]) * 3600) + 
                           (parseFloat(splitTime[1]) * 60) + 
                           (parseFloat(splitTime[2]))
            seconds.push(totalSeconds)
            const objectData = {
                totalSeconds: totalSeconds,
                originalData: data[i]
            }
            newData.push(objectData)
        }
        newData.sort((a, b) => a.totalSeconds - b.totalSeconds)
        this.sortedTimeData = newData
    }

    #rebuildAlphaBody() {
        const body = this.table.getElementsByTagName('tbody')[0];
        const data = this.sortedData;
    
        // Append the sorted rows directly to the body
        for (let i = 0; i < data.length; i++) {
            body.appendChild(data[i]); // Reuse the original row elements
        }
    }
    
    #rebuildOriginalBody() {
        const body = this.table.getElementsByTagName('tbody')[0];
        const data = this.originalData;
    
        // Append the sorted rows directly to the body
        for (let i = 0; i < data.length; i++) {
            body.appendChild(data[i]); // Reuse the original row elements
        }
    }

    #rebuildTimeBody(){
        const data = this.sortedTimeData
        const body = this.table.getElementsByTagName('tbody')[0]
        for (let i = 0; i < data.length; i++){
            body.appendChild(data[i]['originalData'])
        }
    }

    sortAlpha(){
        this.#getBodyData()
        this.#sortAlphaData()
        this.#removeBody()
        this.#rebuildAlphaBody()
    }

    sortTime(){
        this.#getBodyData()
        this.#sortTimeData()
        this.#removeBody()
        this.#rebuildTimeBody()
    }

unsort() {
    console.log("Original Data:", this.originalData);

    if (!this.originalData) {
        console.error("Error: originalData is not initialized. Call a sorting method first.");
        return;
    }

    this.#removeBody();
    this.#rebuildOriginalBody();
    }  
}

I tried to create a deep copy of the original data so when the this.data was sorted it wouldn’t affect the original data but this console.log(“Original Data:”, this.originalData); is prints undefined.

I am not sure what to do after this.

Thank you

Using glob with the aspect-build bazel-examples repository typescript build?

I’m trying to figure out how to build typescript with Bazel and I cloned this repository:

git clone https://github.com/aspect-build/bazel-examples

And ran the ts_project_transpiler example.

cd ts_project_transpiler
bazel build //...

And this works. And I want to use a glob pattern so that I can have a directory with more typescript files in it, and it looks like Bazel has functions for this.

So I tried.

ts_project(
    name = "tsc",
    #srcs = ["big.ts"],
    srcs = glob(["*.ts"]),
    declaration = True,
    declaration_dir = "build-tsc",
    out_dir = "build-tsc",
    source_map = True,
)

However this errors out.

ERROR: /Temp/bazel-examples/ts_project_transpiler/BUILD.bazel:25:11: in ts_project_rule rule //:tsc: 
Traceback (most recent call last):
        File "/private/var/tmp/_bazel_oleersoy/e1e034f754cf70db5f987ffb5af7aef0/external/aspect_rules_ts/ts/private/ts_project.bzl", line 186, column 13, in _ts_project_impl
                fail(no_outs_msg + """
Error in fail: ts_project target //:tsc is configured to produce no outputs.

This might be because
- you configured it with `noEmit`
- the `srcs` are empty
- `srcs` has elements producing non-ts outputs

This is an error because Bazel does not run actions unless their outputs are needed for the requested targets to build.
ERROR: /Users/oleersoy/Temp/bazel-examples/ts_project_transpiler/BUILD.bazel:25:11: Analysis of target '//:tsc' failed
WARNING: errors encountered while analyzing target '//:tsc': it will not be built
WARNING: errors encountered while analyzing target '//:tsc_test_0__deps': it will not be built
WARNING: errors encountered while analyzing target '//:tsc_test': it will not be built
INFO: Analysis succeeded for only 43 of 46 top-level targets
INFO: Analyzed 46 targets (0 packages loaded, 0 targets configured).
INFO: Found 43 targets...
ERROR: /Users/oleersoy/Temp/bazel-examples/ts_project_transpiler/BUILD.bazel:86:15: Executing genrule //:tsc_test_1__deps failed: missing input file '//:build-tsc/big.js'
ERROR: /Users/oleersoy/Temp/bazel-examples/ts_project_transpiler/BUILD.bazel:86:15: Executing genrule //:tsc_test_2__deps failed: missing input file '//:build-tsc/big.js.map'
ERROR: /Users/oleersoy/Temp/bazel-examples/ts_project_transpiler/BUILD.bazel:86:15: Executing genrule //:tsc_test_3__deps failed: missing input file '//:build-tsc/big.d.ts'
ERROR: /Users/oleersoy/Temp/bazel-examples/ts_project_transpiler/BUILD.bazel:86:15: Executing genrule //:tsc_test_3__deps failed: 1 input file(s) do not exist
ERROR: /Users/oleersoy/Temp/bazel-examples/ts_project_transpiler/BUILD.bazel:86:15: Executing genrule //:tsc_test_1__deps failed: 1 input file(s) do not exist
ERROR: /Users/oleersoy/Temp/bazel-examples/ts_project_transpiler/BUILD.bazel:86:15: Executing genrule //:tsc_test_2__deps failed: 1 input file(s) do not exist
INFO: Elapsed time: 0.123s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
FAILED: Build did NOT complete successfully

Any ideas?

Why is my tumblr-hosted website showing me a broken layout on Firefox? [closed]

I have a Tumblr Blog that has a custom layout made up of HTML, CSS, and JS. It’s displaying properly on Chrome and Safari web browsers on both PC and mobile, but as soon as I open the same page on Firefox (and Firefox Developer Edition) it magnifies everything on the page to the point that it’s not easily viewable anymore.

I thought the problem was needing a "word-wrap: break-word;" addition in an element to target the specific text post that’s causing the issue, but that doesn’t seem to fix it. Any other debugging I’ve tried so far was in completely removing all the included Javascript to see if anything related to the added scripts was causing this underlying effect to take place in Firefox alone, but to no avail. I also tried targeting and removing + later modifying the @-moz-document url-prefix() {} element since it directly ties the containers to display changes in Firefox, but any changes to the height and width of the container through that element or edits to how text should work didn’t render any fixes.

Any help in narrowing the problem down to target and fix whatever is causing its entire layout to break, so that it displays properly again on Firefox, would be greatly appreciated!

The website | The code

How to display, edit, and save a date in DD / MMM / YYYY format in Laravel?

I am working on a Laravel project where I need to add a date field in the user profile section(a form). The date should:

  • Be displayed in the format DD / MMM / YYYY (e.g., 25 / Jun / 2024).
  • Allow users to edit/select the date.
  • Send the date to the backend in a regular YYYY-MM-DD format when the form is submitted.
  • Fetch the saved date from the backend and display it in the same DD / MMM / YYYY format when the page is visited.

I tried using <input type="date">, but it displays the date as 25/06/2025, which isn’t the desired format. I also tried following approach:

`
{!! Form::select(‘day’, range(1, 31), null, [‘placeholder’ => ‘Day’, ‘class’ => ‘form-control’]) !!}
{!! Form::select(‘month’, [’01’ => ‘Jan’, ’02’ => ‘Feb’, ’03’ => ‘Mar’, …, ’12’ => ‘Dec’], null, [‘placeholder’ => ‘Month’, ‘class’ => ‘form-control’]) !!}
{!! Form::select(‘year’, range(date(‘Y’), 1900), null, [‘placeholder’ => ‘Year’, ‘class’ => ‘form-control’]) !!}

`

The JavaScript code for aligning the number of days with the selected month and year, feels overly complex for such a simple requirement.

**Is there an easier way to:
**
Display the date in DD / MMM / YYYY format.
Allow users to edit/select the date.
Fetch and display the saved date(dd-mm-yyyy) in the correct format(dd-mmm-yyyy or 16-05-2025) when the page is visited.

Data to be displayed on webapp based on condition selected from the input from google sheets

I have make a webapp for data capturing. If they select a option on webapp then one data value to be auto displayed on webapp from google sheets. I tried with some codes but not succeeds. Example if i select A or B or C or D then a value will insert inside the plan box which data stored in google sheets. Please suggest.

 .heading {
    margin-top: 20px;
    margin-bottom: 10px;
    text-align:center;
    color: black;
    font-size: 60%;
    height: 85px;
  }
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <base target="_top">
  </head>
  <body>
      <div class="heading">
        <h1><b>Data Monitoring</b></h1>
      </div>
  

      <div class="catg">
        <select id="Category">
        <option>A</option>
        <option>B</option>
        <option>C</option>
        <option>D</option>   
        </select>
      </div>


        <div class="mplan">
        <input id="mdata" type="number" value="0" min="0" oninput="validity.valid||(value='');">
        <label>Data Plan</label>
           
        </div>    
 
     <div class="actual">
        <input id="act" type="number">
        <label for="act">actual : </label>
      </div>

     <div class="sub">
        <button id="btn" type="submit" name="action">Submit
        </button>
     </div>
   
      
  </body>
</html>

Ajax calls loop delay or limit [duplicate]

I have a small Ajax function on my site, which makes the same thing for all list elements which are loaded. My problem is, that the list sometimes has 100+ elements and if it makes the Ajax calls I get ERROR 503, so it’s overloading the server. I just want that let’s say 5 calls are fired parallel or at least make some delay between the calls… I’m not a JS expert, I tried with this after Googling but it’s not right, I got “Unexpected identifier: sleep” error…

async function sleep(ms) { 
    return new Promise(resolve => setTimeout(resolve, ms)); 
}

function genContentSecondStep(){
    var list = document.getElementById("mylist").value;
    
    var splitList = list.split(";");
    for(var element of splitList){
        var trimStr = element.trim();
        if(trimStr != ""){
            callApi('gen-content', trimStr);
            await sleep(1000);
        }
    }
}

function callApi(input, element = null) {
    var prm = "";
    var content = document.getElementById("generatedContent").value;

    if (prm.length == 0 && input == 'generate-list') { 
        document.getElementById("generatedContent").innerHTML = "";
        return;
    } else {
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                document.getElementById("generatedContent").innerHTML += this.responseText;
            }
        };

        xmlhttp.open("GET", "api-call.php?func=" + input + "&prm=" + element + "&content=" + content, true);
        
        xmlhttp.send();
    }
}

How to make this? Is it even possible? Thanks.

EDIT.: the api-call.php is working fine and if I limit the list to a few elements or I execute the previous faulty ones after a while it’s also okay, so the amount of Ajax calls is sadly the problem for the server.

EDIT2.: “thanks” for the duplicate, but it’s not even sure, that the await solves the problem, that was ONE of my first ideas only

How to efficiently integrate Blockly for drag-and-drop coding blocks into a React application?

I’m working on a project to integrate Blockly into a React application. The goal is to create an interactive drag-and-drop programming environment to help beginners visualize algorithms and understand programming concepts.

Goals:

  1. Embed a Blockly workspace in a React component.
  2. Dynamically load and save blocks from/to JSON.
  3. Customize the toolbox for algorithm-related blocks.
  4. Ensure smooth performance as the number of blocks grows.

What I’ve Tried:

  • Used @blockly/react for basic embedding.
  • Defined blocks using JSON but faced issues with dynamically reloading them.
  • Customized the toolbox, but UI responsiveness drops with larger datasets.

Questions:

  • What are the best practices for integrating Blockly with React to ensure performance and scalability?
  • How can I dynamically update the workspace without unnecessary re-renders?
  • Are there libraries or patterns for saving/loading blocks efficiently in a React app?

Any guidance, resources, or code examples would be greatly appreciated!

Previous useState value is used when a next action is triggered

I’m trying to complete FreeCodeCamp “Front End Development Libraries” course. One of the final projects there is to build a simple calculator. More details about it can be found here

When I run automated tests to verify that the functionality works as expected, some of them fail (Click on Hamburger menu -> Select JavaScript Calculator -> Run Tests).

For example, when I manually click the formula “5 * 5.5”, it returns 27.5 as expected. However, it’s written in test #12 that the result is 302.5 instead of 27.5.

I realized that it happens because a new test sometimes sums up the result of the previous calculation to the first number of the next test (it calculated “55 * 5.5” instead of “5 * 5.5”). I was trying to debug using console logs and React debugging tools. I believe it’s caused due to the asynchronous useState. useEffect hook is suggested by many tutorials but I’m not sure if I use it in a right way.. I keep formula and output in useState variables like this:

const [formula, setFormula] = useState([]);
const [output, setOutput] = useState("0"); 
const [reset, setReset] = useState(false);

here is my AC function:

const handleAC = () => {
  setFormula([]);
  setOutput("0");
  setReset(true);
}

And useEffect hook:

useEffect(() => {
  if (reset) {
    // Perform any operations that should happen after reset
    console.log("Reset complete");
    console.log("AC clicked: ", formula);
    setReset(false);
  }
}, [formula, output, reset]);

I have an assumption that the tests run very fast and formula’s value isn’t updated frequent enough. However, I don’t have much experience with React and may be completely wrong… So I pushed the code to Github to share the complete file App.js. And temporary ran the app on Heroku so you could see how it actually works.

I will be happy to share more details if needed and thank you in advance!

I tried to wait for the state to be updated using useEffect hook, callback functions and so on. Also, I spent quite a lot of time by debugging the behavior but didn’t manage to get it working.

How to display bold text in a when content is added by JS?

The second element doesn’t display the expected result. Why and how to fix?

function process(sentence,element) {
    
    const words = sentence.split(' ');
    const container = document.getElementById(element);
    let index = 0;

    container.innerHTML = '';

    for (let i = 0; i < words.length; i++) {
        //console.log(words[i]);
        container.innerHTML += words[i] + ' '; // Display the word
    }
}

process("the quick <b>fox</b> jumps",'e1');   //displayed the word 'fox' as expected in bold
process("the quick <b> fox </b> jumps",'e2'); //displayed the word 'fox' as plain text, not as expected
div{
  border:1px solid #999;
  margin: 0 0 10px 0;
  display:block;
  font-size:22px
  }
<div id="e1"></div>
<div id="e2"></div>

Replace DDSC component code with Javascript code

I am working on an ASP.NET Web Application that uses DDSC components with Javascript in an ASPX Page.
We need to remove/ retire DDSC components code

Following are the DDSC lines of Code that Need to be replaced with javascript code.

DDSC.WebPart(WPQ).Properties.GetValue("applicationCode", "someGUID");
DDSC.Properties.PutValueSession('applicationCode', 'someID', 0);

DDSC.Events.Raise("applicationCode", "onWindowOpenRequest", WPQ, Data, true);

DDSC.WebPart(WPQ).Close();

Any help or advice to replace the above DDSC codes with Javascript code.

Thanks in advance for helping.

Why don’t my platform and packageType states update correctly?

I have Index, LandingButtons, SelectPackages components. Index has platform and packageType states, which set initial states of SelectPackages component. I pass a function to LandingButtons component to update these states. They update, but for some reason they aren’t set in SelectPackages component.

Index.jsx

import SelectPackages from "../components/structure/landing_page/SelectPackages.jsx";
import LandingHeader from "../components/structure/landing_page/header/LandingHeader.jsx";
import HowItWorks from "../components/structure/landing_page/HowItWorks.jsx";
import FAQ from "../components/structure/landing_page/FAQ.jsx";
import LandingReviews from "../components/structure/landing_page/LandingReviews.jsx";
import LandingButtons from "../components/structure/landing_page/LandingButtons.jsx";
import Features from "../components/structure/landing_page/Features.jsx";
import {useState} from "react";

export default function Index() {
    const [platform, setPlatform] = useState("instagram")
    const [packageType, setPackageType] = useState("discussions")
    return (
        <>
            <LandingHeader/>
            <LandingButtons onPackageSelected={(newPlatform, newPackageType) => {
                console.log("Selected platform:", newPlatform, "Selected package type:", newPackageType);
                setPlatform(newPlatform);
                setPackageType(newPackageType);
            }}/>
            <HowItWorks/>
            <Features/>
            <SelectPackages initialPlatform={platform} initialPackageType={packageType}/>
            <FAQ/>
            <LandingReviews/>
        </>

    );
}

LandingButtons.jsx

import twocheckout1 from "../../../assets/img/landing/twocheckout1.png";

const buttons = [
    { text: "Instagram discussions", platform: "instagram", packageType: "discussions" },
    { text: "Instagram comments", platform: "instagram", packageType: "comments" },
    { text: "Instagram discussions + comments", platform: "instagram", packageType: "discussions+comments" },
    { text: "TikTok discussions", platform: "tiktok", packageType: "discussions" },
    { text: "TikTok comments", platform: "tiktok", packageType: "comments" },
    { text: "TikTok discussions + comments", platform: "tiktok", packageType: "discussions+comments" },
];

export default function LandingButtons({onPackageSelected}) {
    return (
        <div id="landing-buttons" className="text-center space-y-12 mb-16">
          

            <div className="grid grid-cols-3 gap-4 w-3/5 mx-auto">
                {buttons.map((button, index) => (
                    <button
                        key={index}
                        className="text-white font-semibold py-4 px-5 rounded-2xl text-center no-underline
                                    bg-gradient-to-tr from-yellow-500 to-pink-500 via-pink-500"
                        onClick={() => onPackageSelected(button.platform, button.packageType)}
                    >
                        {button.text}
                    </button>
                ))}
            </div>
            <img src={twocheckout1} className="mx-auto"/>
        </div>

    );
}

SelectPackages.jsx

import {useEffect, useState} from "react";
import DiscussionsPackages from "../../packages/DiscussionsPackages.jsx";
import CommentsPackages from "../../packages/CommentsPackages.jsx";
import DiscussionsCommentsPackages from "../../packages/DiscussionsCommentsPackages.jsx";
import {useNavigate} from "react-router";
import {getPrices} from "../../../services/infoRequests.js";

export default function SelectPackages({initialPlatform, initialPackageType}) {
    const navigate = useNavigate();
    const [platform, setPlatform] = useState(initialPlatform);
    const [packageType, setPackageType] = useState(initialPackageType);
    const [selectedPackage, setSelectedPackage] = useState(null);
    const [commentsPackages, setCommentsPackages] = useState({});
    const [discussionsPrices, setDiscussionsPrices] = useState({});
    const [slidersLimits, setSlidersLimits] = useState({}); 
    console.log("1 platform:", platform); //shows initial "instagram" value
    console.log("1 package type:", packageType);
    console.log("2 platform:", initialPlatform); //shows updated "tiktok" value
    console.log("2 package type:", initialPackageType);
    useEffect(() => {
        getPrices().then((res) => {
            setCommentsPackages(res.data.commentsPackages);
            setDiscussionsPrices(res.data.discussionsPrices);
            setSlidersLimits(res.data.discussionsSlidersLimits);
        });
    }, [platform, packageType]);


    function handlePackageSelected(_selectedPackage) {
        setSelectedPackage(_selectedPackage);
    }


    return (
        <div id="packages" className="mx-32 my-20 text-center">
            <h1>Packages</h1>
            <div id="platformButtons" className="space-x-10 my-5">
                <button
                    className={platform === "instagram" ? "bg-blue-500" : ""}
                    onClick={() => setPlatform("instagram")}>
                    Instagram
                </button>
                <button
                    className={platform === "tiktok" ? "bg-blue-500" : ""}
                    onClick={() => setPlatform("tiktok")}>
                    TikTok
                </button>
            </div>
            <div id="typeButtons" className="space-x-10 my-10">
                <button
                    className={packageType === "discussions" ? "bg-blue-500" : ""}
                    onClick={() => setPackageType("discussions")}>
                    Discussions
                </button>
                <button
                    className={packageType === "comments" ? "bg-blue-500" : ""}
                    onClick={() => setPackageType("comments")}>
                    Comments
                </button>
                <button
                    className={packageType === "discussions+comments" ? "bg-blue-500" : ""}
                    onClick={() => setPackageType("discussions+comments")}>
                    Discussions + comments
                </button>
            </div>
            <div id="packages-options" className="text-left mb-10">
                {
                    packageType === "discussions" ?
                        <DiscussionsPackages
                            prices={discussionsPrices}
                            slidersLimits={slidersLimits}
                            onPackageSelected={handlePackageSelected}
                        /> :
                        packageType === "comments" ?
                            <CommentsPackages
                                packages={commentsPackages}
                                onPackageSelected={handlePackageSelected}
                            /> :
                            <DiscussionsCommentsPackages
                                discussionsPrices={discussionsPrices}
                                slidersLimits={slidersLimits}
                                commentsPackages={commentsPackages}
                                onPackageSelected={handlePackageSelected}
                            />
                }
            </div>
        
        </div>
    )
}

Is there a way to declare an object property without initializing it?

A.S.: Object property order in JS is a very complicated topic. For my intents and purposes, only insertion order matters.

TL;DR: Is there a way to declare an object property without giving it a value?

const user = { name: unset, age: 42 }


I have a set of asynchronous functions, each returning a value associated with a unique key. They are then invoked in parallel to construct an object with key-value pairs used as entries (properties). Something like this:

const props = {}
const propsSet = getters.map(async ([key, getValue]) => {
  props[key] = async getValue()
})

await Promise.all(propsSet)

return props

Try it.

Sine all of this is asynchronous, the order of properties in props is all over the place: I get sometimes { foo: …, bar: … }, sometimes { bar: …, foo: … }. I could fix that by associating each getter with a sequence number. But a much easier solution is to just initiate the properties as soon as possible; due to how event loop works, this is basically a guarantee that properties of props will be ordered the same as in getters:

const propsSet = getters.map(async ([key, getValue]) => {
    props[key] = null // or any other initialization token
    props[key] = await getValue()
})

In pure JS this a perfectly normal thing to do, but in TS this is usually a compiler error (since arbitrary “initialization token” isn’t assignable to strictly typed properties of props); so, I have to do shush the compiler, which I don’t like to do:

// @ts-expect-error
values[key] = null

Try it.

I’ve realized that what I basically need is very similar to declaring variables separately from initializing them, – like in old-school JS style:

var value1, value2

value1 = 42
value2 = 17

Is there any existing or upcoming (proposal) way of declaring object properties without initializing them?

Note that I’m not asking about ways of ordering properties. There are many strategies to do that, including usage of the aforementioned sequence numbers (e.g., array indexes).