Different code update with No replies from Gemini

I’ve tested and uploaded my code to the link https://github.com/Dio-Damar-Danendra-Portofolio/Chatbot-Dio-Damar-Danendra (I recently updated on 9:24 A.M in Western Indonesian Time). I have tested with different usernames and I test the messages but it come with the same error message (No reply from Gemini). Please check and revise the errors. (Note: I already set the API key from the https://aistudio.google.com/app/apikey)

I have tested with different usernames and I test the messages but it come with the same error message (No reply from Gemini). I expected to be functional as any other chatbots, but in reality it comes with that Error message from invalid authentication credentials until the reply reads “Error: No reply from Gemini”. I have tried so many solutions.

Make array with osclass custom category while loop

How can i make an array of veriables using a while loop

I am using osclass for a uni project and i find no way whatsoever to make a variable for the custom catagory fields.

I have made Identifiers for the custom catagories and have tried many different approaches to grab and echo the custom catagory value elsewhere on the page other than in the current catagory.

I cannot isolate the custom catagory values by any means.

My only option i am thinking is making or buying a plugin , OR using a PHP veriable array

Below is the code used to display the custom catagory values on my osclass page

<?php if( osc_count_item_meta() >= 1 ) { ?> 
   
          <?php while ( osc_has_item_meta() ) { ?>
          
                    <?php if(osc_item_meta_value()!='') { ?> 
                   
                   
                    // I WOULD LIKE TO MAKE MAKE AN ARRAY OF VERIABLES SO I CAN USE THE CUSTOM CATAGORY DATA 
                    // TRIED SO FAR if(osc_item_meta_name()!='') {  $caughtcountry = osc_item_meta_value('country'); } 
                    // BUT THIS APPROACH DOES NOT WORK 

                    <?php } ?>
            
          <?php } ?>
          
          
      
    <?php } ?>`
    

I have tried using the identifiers that i added to the catagory in Admin panel

I have also tried using the Current PHP but cannot grab the values of specific custom catagories

Below is an example of one of my attempts to grab a custom catagory value but it only shows the 1st value within the values instead of cataching the ‘age’ value using the ‘age’ identifier i used.

 <?php if( osc_count_item_meta() >0 ) {  // The If osc_count_item_meta() >=1 
      if(osc_item_meta_value('age')!='') {  $caughtage = osc_item_meta_value('age'); }  else { $caughtage=''; }
                
    }   else { $caughtage=''; }
     ?>

React Axios POST request returns success but no Preview/Response in Chrome Network DevTools

I am building a signup feature in React. My API is working fine — when I hit the endpoint in Postman or cURL, I get a 201 Created response with JSON.

But in Chrome DevTools → Network tab, when I trigger the API from React, I see 201 Created in the Headers, but in Preview/Response it shows:
Failed to load response data: No data found for resource with given identifier
My Code This is for Sign up Request.

import axios from "axios";
import { useState } from "react";

export default function Signup() {
  const [formData, setFormData] = useState({
    name: "",
    email: "",
    password: ""
  });

  const handleSignUp = async () => {
    try {
      const res = await axios.post("http://localhost:3000/app/users/sign-up", formData);
      console.log("Response:", res.data);
      alert("User created successfully");
    } catch (err) {
      console.error("Signup failed:", err);
    }
  };

  return (
   <form className="mt-8 space-y-6" >
    <div className="rounded-md -space-y-px">
     <div>
      <input
        type="text"
        placeholder="Name"
        value={formData.name}
        onChange={(e) => setFormData({ ...formData, name: e.target.value })}
      />
      <input
        type="email"
        placeholder="Email"
        value={formData.email}
        onChange={(e) => setFormData({ ...formData, email: e.target.value })}
      />
      <input
        type="password"
        placeholder="Password"
        value={formData.password}
        onChange={(e) => setFormData({ ...formData, password: e.target.value })}
      />
      <button type="submit" onClick={handleSignUp}>
        Sign Up
      </button>
    </div>
   </div>
  </form>
     
  );
}

  • What I expected:

    To see the JSON response in the Preview/Response tab in Network DevTools after the request succeeds.

  • What I got:

    The request shows 201 Created in Headers, but Preview/Response says

    Failed to load response data: No data found for resource with given identifier

Why is this happening, and how can I fix it?

How to view the latest version of a kml file in my browser?

I uploaded a kml file to my website and viewed the result in Google Chrome. Then I noticed a waypoint was missing. I added that point to the kml file using Google Earth and then re-uploaded the file. When I reopened the new file in my browser, the added point wasn’t visible. I think it was because a cache (but not the browser cache) was still showing the old version. What should I do to always see the latest version in my browser?

How to save Google Cloud GET Object API mediaLink response to local storage?

I wrote this code that uses Google’s Cloud API to get an object from my bucket and download it. It works perfectly when I had my bucket set to public (allUsers added to Principal w/ all the required roles, then I could just redirect to the mediaLink) but I need it to be more secure. Now I can’t just use the mediaLink to redirect to another tab since that results in an Anonymous user error.

downloadSubmittalBucket(item) {
            this.loading = true

                axios
                .get(`https://storage.googleapis.com/storage/v1/b/bucket-name-here/o/` + item, 
                {
                    headers: { 
                        'Authorization': 'Bearer ' + sessionStorage.getItem("access_token")
                    }
                })
                .then((response) => {
                    // window.open(response.data.mediaLink)
                    this.saveSubmittalBucket(response.data)
                    // console.log(response)
                    

                })
                .catch((err) => {
                    console.log(err)
                });
        },  
saveSubmittalBucket(item){
            axios
                .get(item.mediaLink, 
                {
                    headers: { 
                        'Authorization': 'Bearer ' + sessionStorage.getItem("access_token")
                    }
                })
                .then((response) => {
                    console.log(response)
                    // A bunch of stuff that didn't work:
                    // I've tried using: 
                    // new blob -> filesaver.js
                    // window.open(response.data) -> ends up with anonymous user
                    // base64 -> blob
                    // I've also tried using @google-cloud/storage, unfortunately it doesn't match my use case, since it requires gcloud auth login.
                    // Same with signed URLs, also requires gcloud auth login

                    //Not really sure how this response works too. What is it even?

                })
                .catch((err) => {
                    console.log(err)
                });
}

response.data

So basically the code right now just results in the response above, and I don’t really know how to save it locally. I’ve also looked into using @google-cloud/storage but unfortunately it doesn’t really fit my use case.

Funnily enough, I can download the output just fine using the mediaLink on Postman with the required token, so I’m pretty sure authorization is not an issue.

I’m basically stuck now, don’t really know how to proceed from here.

Any help will be appreciated.

React – Passing event handlers that need arguments as props to child components

I’m new to React, so when I finished the Tic-Tac-Toe Tutorial from the documentation, I started doing the challenges to improve the game and practice. I got stuck at the second challenge:

“2. Rewrite Board to use two loops to make the squares instead of hardcoding them.”

This was the Board component before i started the challenge.

function Board({xIsNext, squares, onPlay}) {

  function handleClick(i) {
    if (squares[i] || calculateWinner(squares)) return;
  
    const nextSquares = squares.slice();
    xIsNext ? (nextSquares[i] = "X") : (nextSquares[i] = "O");
    onPlay(nextSquares)
  }

  const winner = calculateWinner(squares);
  let status;
  status = winner ? "Winner: "+winner : "Next player: "+(xIsNext ? "X" : "O");

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

Seeing the pattern that there was in the repetition of the rows and squares, I rewrote the code into this.

function Board({xIsNext, squares, onPlay}) {

  function handleClick(i) {
    if (squares[i] || calculateWinner(squares)) return;
  
    const nextSquares = squares.slice();
    xIsNext ? (nextSquares[i] = "X") : (nextSquares[i] = "O");
    onPlay(nextSquares)
  }

  const squareComponents = []
  const rowComponents = []

  for (i = 0; i < 9; i++) {
    squareComponents.push(<Square key={i} value={squares[i]} onSquareClick={() => handleClick(i)}/>);
  }
  
  for (i = 0; i < 3; i++) {
    rowComponents.push(
      <Row key={i}>
        {squareComponents.splice(0,3)}
      </Row>
    )
  }

  const winner = calculateWinner(squares);
  let status;
  status = winner ? "Winner: "+winner : "Next player: "+(xIsNext ? "X" : "O");

  return (
    <>
      <div className="status">{status}</div>
      {rowComponents}
    </>
  );
}

The page renders, but when you click in any of the squares in the board, the “X” appears only in the fourth square. It’s like all of the click handlers of the Square components are referencing the fourth square. Why does that happen?

My solution to this, after trying many different things, was passing the parameter of the event handler function as a prop to be used in the Square component. So I changed the first for loop in the Board component to this:

squareComponents.push(<Square key={i} value={squares[i]} onSquareClick={handleClick} onSquareClickArgument={i}/>);

And I changed the Square component to this:

function Square(props) {
  return (
    <button className="square" onClick={() => props.onSquareClick(props.onSquareClickArgument)}> 
      {props.value}
    </button>
  );
}

It worked. But why my first solution to this challenge did not and this does?

i18n issue with Next.js

I was trying to internationalize a website for a client of mine.
The website should have the standard languages ​​IT and then EN.

I’m having a problem with the next-intl library and I can’t seem to figure it out.

I am using the Router App and currently my project has the following configuration:

  • @/messages contains both JSON files for the two languages ​​IT and EN
  • This is the next.config.mjs file:
import createNextIntlPlugin from "next-intl/plugin";
const withNextIntl = createNextIntlPlugin();
const nextConfig = {};
export default withNextIntl(nextConfig);
  • This is @/i18n/request.js file:
import { getRequestConfig } from "next-intl/server";

export default getRequestConfig(async ({ locale }) => {
  const l = locale ?? "it"; // fallback
  return {
    locale: l,
    messages: (await import(`../messages/${l}.json`)).default,
  };
});
  • This is the middleware.js root file
import createMiddleware from "next-intl/middleware";

export default createMiddleware({
  locales: ["it", "en"],
  defaultLocale: "it",
  localePrefix: "always",
});

// Escludi asset, api, ecc.
export const config = {
  matcher: ["/((?!api|_next|.*\..*).*)"],
};
  • This is the Root Layout in [locale]
// app/[locale]/layout.js
import localFont from "next/font/local";
import { Montserrat } from "next/font/google";
import "../globals.css";
import Header from "@/components/header/header";
import Footer from "@/components/footer/footer";
import Script from "next/script";
import { notFound } from "next/navigation";

import { getMessages, setRequestLocale } from "next-intl/server";
import { NextIntlClientProvider } from "next-intl";

export const dynamic = "force-static"; // opzionale, se tutto è statico

const operetta = localFont({
  src: [
    {
      path: "../../public/fonts/Operetta12-Regular.otf",
      weight: "400",
      style: "normal",
    },
    {
      path: "../../public/fonts/Operetta12-ExtraLight.otf",
      weight: "300",
      style: "normal",
    },
    {
      path: "../../public/fonts/Operetta12-SemiBold.otf",
      weight: "600",
      style: "normal",
    },
  ],
  variable: "--fontHeading",
  display: "swap",
});

const montserrat = Montserrat({
  variable: "--fontBody",
  subsets: ["latin"],
  weight: "400",
});

export function generateStaticParams() {
  return ["en", "it"].map((l) => ({ locale: l }));
}

export const metadata = {
  title: {
    default: "Cantina Scrinzi Saltarius",
    template: "%s | Cantina Scrinzi Saltarius",
  },
  description:
    "Saltarius Trento Doc: eleganza e complessità da Chardonnay e Pinot Nero, oltre 60 mesi di affinamento e una tradizione familiare tramandata da generazioni.",
  icons: {
    icon: [
      { rel: "icon", url: "/favicon.ico" },
      { rel: "icon", type: "image/svg+xml", url: "/favicon.svg" },
      {
        rel: "icon",
        type: "image/png",
        sizes: "96x96",
        url: "/favicon-96x96.png",
      },
    ],
    apple: [
      {
        rel: "apple-touch-icon",
        sizes: "180x180",
        url: "/apple-touch-icon.png",
      },
    ],
  },
  manifest: "/site.webmanifest",
  openGraph: {
    title: "Cantina Scrinzi Saltarius",
    description:
      "Saltarius Trento Doc: eleganza e complessità da Chardonnay e Pinot Nero, oltre 60 mesi di affinamento e una tradizione familiare tramandata da generazioni.",
    url: "https://scrinzi.com",
    siteName: "Cantina Scrinzi Saltarius",
    images: [
      {
        url: "https://scrinzi.com/og-image.webp",
        width: 1200,
        height: 630,
        alt: "Cantina Scrinzi Saltarius",
      },
    ],
    locale: "it_IT",
    type: "website",
  },
  twitter: {
    card: "summary_large_image",
    title: "Cantina Scrinzi Saltarius",
    description:
      "Saltarius Trento Doc: eleganza e complessità da Chardonnay e Pinot Nero, oltre 60 mesi di affinamento e una tradizione familiare tramandata da generazioni.",
    images: ["https://scrinzi.com/og-image.webp"],
  },
};

export const viewport = { width: "device-width", initialScale: 1 };

export default async function RootLayout({ children, params }) {
  const { locale } = await params;

  if (!["en", "it"].includes(locale)) {
    return notFound();
  }

  console.log("Requested Locale: ", locale);

  setRequestLocale(locale);
  const messages = await getMessages();

  console.log("Layout Messages: ", messages);
  console.log("Layout Locale: ", locale);

  return (
    <html lang={locale}>
      <Script src="https://cdn-cookieyes.com/client_data/9b29b34c372b76504e2ff609/script.js" />
      <body className={`${operetta.variable} ${montserrat.variable}`}>
        <NextIntlClientProvider messages={messages} locale={locale}>
          <Header locale={locale} />
          {children}
          <Footer locale={locale} />
        </NextIntlClientProvider>
      </body>
    </html>
  );
}
  • This is the Header component where I had to change only one word:
import Link from 'next/link';
import styles from './header.module.css';
import Image from 'next/image';
import { useTranslations } from 'next-intl';
import { getTranslations } from 'next-intl/server';

export default async function Header({ locale }) {
  const t = await getTranslations('Header');

  console.log("Header Messages: ", t('contacts'));

  return (
    <header className={styles.header}>
      <div className={`container ${styles.headerContainer}`}>
        <Link href={`/${locale}`} className={styles.headerLogo} aria-label="Home">
          <Image src="/logo.svg" alt="Cantina Scrinzi Saltarius Logo" width={50} height={50} />
          <span className={styles.logoText}>Saltarius</span>
        </Link>
        <nav className={styles.nav}>
          <Link href={`/${locale}/contatti`} className={styles.navLink}>
            {t('contacts')}
          </Link>
        </nav>
      </div>
    </header>
  );
}

I can’t understand why, however, even if I visit /it or /en, the languages ​​are always taken from /it, unless I remove the fallback, but in that case, it tells me that it can’t find the undefined.json file.

Am I doing something wrong when passing parameters?
These are the console.logs:

Requested Locale:  en
Layout Messages:  {
  Header: { contacts: 'Contatti' },
  Intro: {
    leftTitle: 'L’eleganza di un Metodo Classico Trento Doc',
    leftText: '**Saltarius** nasce da un perfetto equilibrio tra **Chardonnay (60%)** e **Pinot Nero (40%)**, coltivati con cura nelle colline roveretane. Le uve, allevate a pergola semplice trentina e raccolte a rese contenute, riposano oltre 60 mesi sui lieviti, sviluppando complessità, finezza e grande eleganza. **Un Trento Doc capace di raccontare la sua terra in ogni sorso.**',
    rightTitle: 'Una passione di famiglia tramandata da generazioni',
    rightText: 'Saltarius è molto più di un vino: è la storia di una famiglia che da quattro generazioni custodisce l’arte della viticoltura. Dal bisnonno Achille al nipote Andrea, giovane enotecnico, ogni generazione ha portato avanti con dedizione un sogno fatto di tradizione e innovazione. Il primo raccolto del 2019, realizzato insieme al nonno Franco, ha segnato l’inizio di una missione: preservare un sapere artigianale sempre più raro e valorizzare un territorio unico.'
  },
  Pills: [
    {
      title: 'Territorio unico',
      text: 'Uve allevate sulle colline roveretane, accarezzate dal sole e dal vento dell’Ora del Garda.'
    },
    {
      title: 'Metodo artigianale',
      text: 'Oltre 60 mesi di affinamento sui lieviti per un Trento Doc di rara complessità.'
    },
    {
      title: 'Tradizione di famiglia',
      text: 'Quattro generazioni di passione e dedizione, unite dall’amore per la viticoltura.'
    }
  ]
}
Layout Locale:  en
Header Messages:  Contatti

(As you can see the locale is /en but the data is taken in Italian)

Can anyone else shed some light on this? Am I doing something wrong?

Thanks in advance

I want to ask codes [closed]

I want to ask some code because I’m willing to study about cybersecurity So I want to study a code for legal and ethical way of hacking

I want to try some testing penetration for legal purposes only and school purpose studying

If I place my signature on a page its being put higher on the same page after I save the document, how can I solve this using Javascript

signature functionality in pdf documents

const embedSignatureInPdf = async () => {
    if (!signatureData) return null;

    try {
        let existingPdfBytes = null;

        if (uploadedPdfBytes) {
            existingPdfBytes = uploadedPdfBytes;
        } else if (pdfUrl) {
            try {
                const response = await fetch(pdfUrl);
                if (!response.ok) {
                    throw new Error(`Failed to fetch PDF: ${response.status} ${response.statusText}`);
                }
                existingPdfBytes = await response.arrayBuffer();
            } catch (fetchError) {
                console.error('Error fetching PDF:', fetchError);
                return null;
            }
        } else {
            return null;
        }

        const pdfDoc = await PDFDocument.load(existingPdfBytes, {
            ignoreEncryption: true,
            updateMetadata: false,
            throwOnInvalidObject: false
        });

        const helveticaFont = await pdfDoc.embedFont(StandardFonts.HelveticaOblique);
        const pages = pdfDoc.getPages();


        if (pages.length === 0) {
            return null;
        }


        const page = pages[selectedPageIndex];

        const iframe = iframeRef.current;
        const container = pdfContainerRef.current;
        if (!iframe || !container) {
            return null;
        }

        // Get container dimensions (more accurate than iframe)
        const containerRect = container.getBoundingClientRect();
        const displayWidth = containerRect.width;
        const displayHeight = containerRect.height;

        const pdfWidth = page.getWidth();
        const pdfHeight = page.getHeight();
        const scaleX = pdfWidth / displayWidth;
        const scaleY = pdfHeight / displayHeight;

        const sigPos = signatureDisplayPos || { left: 100, top: 100 };

        // Adjust for any container padding/offset
        const x = sigPos.left * scaleX;
        // PDF coordinates start from bottom-left, so we need to flip Y
        // Increase downward adjustment to three times more than current amount
        const y = pdfHeight - (sigPos.top * scaleY) - 60; // Move 60 pixels down (three times the current 20)

        if (signatureData.method === 'typed') {
            const fontSize = 24;
            page.drawText(signatureData.value, {
                x,
                y: y + fontSize, // Keep the text baseline adjustment
                size: fontSize,
                font: helveticaFont,
                color: rgb(0, 0, 0),
            });

            pdfDoc.setTitle(`Signed: ${pdfDoc.getTitle() || 'Document'}`);
            pdfDoc.setSubject('Electronically Signed Document');

        } else if (signatureData.method === 'drawn' || signatureData.method === 'image') {
            let image;
            try {
                if (signatureData.value.startsWith('data:image/jpeg')) {
                    image = await pdfDoc.embedJpg(signatureData.value);
                } else {
                    image = await pdfDoc.embedPng(signatureData.value);
                }

                const dims = image.scale(0.5);

                page.drawImage(image, {
                    x,
                    y: y + dims.height, 
                    width: dims.width,
                    height: dims.height,
                });

                pdfDoc.setTitle(`Signed: ${pdfDoc.getTitle() || 'Document'}`);
                pdfDoc.setSubject('Electronically Signed Document');
            } catch (err) {
                console.error('Error embedding signature image:', err);
                throw err;
            }
        }

        const pdfBytes = await pdfDoc.save({
            useObjectStreams: false,
            addDefaultPage: false,
            objectsPerTick: 50
        });

        const blob = new Blob([pdfBytes], { type: 'application/pdf' });
        return blob;

    } catch (err) {
        console.error('Failed to embed signature:', err);
        throw err;
    }
};

i have this code but when i put the signature on a specific position , its put higher than the position i have put it after i have saved the document. i want the signature to remain on the position i have put it.

Number Array to Object conversion shorting the Object Keys in ascending order

I tried turn a Array of Number into an Object whose keys will be array Items and values will be true.

But i got this An object whose keys are arranged in ascending order. And The repeated No.s aren’t displayed ?

this was my code

arr1=[2,1,6,4,9,3,2,6]
let mapped={};
function mapper(array){
    for (let i=0; i<array.length; i++){
        const item = array[i];
        mapped[item] = true;
    }
}
mapper(arr1);
console.log(mapped);

I WAS EXPECTING SOMETHING LIKE THIS :
{ '2': true, '1': true, '6': true, '4': true, '9': true, '3': true,, '2': true, '6': true }

But I got this answer:
{ '1': true, '2': true, '3': true, '4': true, '6': true, '9': true }

i can think that due to unique keys the duplicate may have merged together but arranging them in Ascending order is something i can’t understand

How to show audio waveform inside the player (like Telegram voice messages) in Vue + Tailwind? [closed]

enter image description here
I’m building a call center dashboard where we need to add recorded conversations. The audio should be displayed with a waveform inside the player itself, not as a separate element. Something like this example:

Play/Pause button on the left

Duration on the right

The progress bar is replaced by a waveform visualization

Tech stack: Vue 3 + Tailwind CSS.
Requirements:

I don’t need advanced audio editing or studio-level tools

Just a simple inline waveform (like Telegram or WhatsApp voice messages)

What are some simple libraries or Vue components that can do this, or how can I achieve it?

I looked into using Wavesurfer.js, but it felt too heavy for my use case.

Crud operation using html,css and javascript [closed]

I am performing crud operation using html,css and javascript. In this while i m running the web page it’s displaying the form structure but when i am giving the input its not taking or input is not getting saved. how i should resolve this and what mistake am i making there? why my data is not stored ,without storing data i can not perform the crud operation.

var selectedRow = null

function onFormSubmit() {
    if (validate()) {
        var formData = readFormData();
        if (selectedRow == null)
            insertNewRecord(formData);
        else
            updateRecord(formData);
        resetForm();
    }
}

function readFormData() {
    var formData = {};
    formData["fullName"] = document.getElementById("fullName").value;
    formData["empCode"] = document.getElementById("empCode").value;
    formData["salary"] = document.getElementById("salary").value;
    formData["city"] = document.getElementById("city").value;
    return formData;
}

function insertNewRecord(data) {
    var table = document.getElementById("employeeList").getElementsByTagName('tbody')[0];
    var newRow = table.insertRow(table.length);
    cell1 = newRow.insertCell(0);
    cell1.innerHTML = data.fullName;
    cell2 = newRow.insertCell(1);
    cell2.innerHTML = data.empCode;
    cell3 = newRow.insertCell(2);
    cell3.innerHTML = data.salary;
    cell4 = newRow.insertCell(3);
    cell4.innerHTML = data.city;
    cell4 = newRow.insertCell(4);
    cell4.innerHTML = `<a onClick="onEdit(this)">Edit</a>
                       <a onClick="onDelete(this)">Delete</a>`;
}

function resetForm() {
    document.getElementById("fullName").value = "";
    document.getElementById("empCode").value = "";
    document.getElementById("salary").value = "";
    document.getElementById("city").value = "";
    selectedRow = null;
}

function onEdit(td) {
    selectedRow = td.parentElement.parentElement;
    document.getElementById("fullName").value = selectedRow.cells[0].innerHTML;
    document.getElementById("empCode").value = selectedRow.cells[1].innerHTML;
    document.getElementById("salary").value = selectedRow.cells[2].innerHTML;
    document.getElementById("city").value = selectedRow.cells[3].innerHTML;
}
function updateRecord(formData) {
    selectedRow.cells[0].innerHTML = formData.fullName;
    selectedRow.cells[1].innerHTML = formData.empCode;
    selectedRow.cells[2].innerHTML = formData.salary;
    selectedRow.cells[3].innerHTML = formData.city;
}

function onDelete(td) {
    if (confirm('Are you sure to delete this record ?')) {
        row = td.parentElement.parentElement;
        document.getElementById("employeeList").deleteRow(row.rowIndex);
        resetForm();
    }
}
function validate() {
    isValid = true;
    if (document.getElementById("fullName").value == "") {
        isValid = false;
        document.getElementById("fullNameValidationError").classList.remove("hide");
    } else {
        isValid = true;
        if (!document.getElementById("fullNameValidationError").classList.contains("hide"))
            document.getElementById("fullNameValidationError").classList.add("hide");
    }
    return isValid;
}
<table>
    <tr>
        <td>
          <form onsubmit="event.preventDefault();onFormsubmit();" autocomplete="off">
            <div>
            <label>Full Name</label>
            <input type="text" name="fullName">
            </div>
            <div>
               <label>Emp Code</label>
            <input type="text" name="empCode"> 
            </div>
            <div>
                <label>Salary</label>
            <input type="text" name="salary">
            </div>
            <div>
                <label>City</label>
            <input type="text" name="city">
            </div>
            <div class="form-action-buttons">
                <input type="submit" value="Submit">
            </div>
          </form>  
        </td>
        <td>
            <table class="list" id="employeeList">
                <thead>
                    <tr>
                        <th>Full Name</th>
                        <th>EMP Code</th>
                        <th>Salary</th>
                        <th>City</th>
                    </tr>
                </thead>
            </table>
        </td>
    </tr>
</table>

TypeScript: Type an Array of Generics with Dynamic Type Inference for Dependent Properties

I’m working on a form configuration system in TypeScript and I’m facing a type inference challenge. I need to define a type for an array of configuration objects, where each object has a query property that returns a promise of an array of a specific type. The key requirement is that other properties within the same configuration object (getOptionLabel and getOptionValue) must dynamically infer their parameter types based on the return type of that specific object’s query.

Here’s an example of the formConfig array I want to type-check:

const formConfig = [
    {
        name: 'category',
        label: 'Category',
        placeholder: 'select a category',
        query: async () => [{id: 1, categoryName: 'games'}, {id: 2, categoryName: 'movies'}],
        getOptionLabel: ({categoryName}) => categoryName,
        getOptionValue: ({id}) => id
    },
    {
        name: 'user',
        label: 'User',
        placeholder: 'select a user',
        query: async () => [{userId: 'u1', fullName: 'Alice Smith'}, {userId: 'u2', fullName: 'Bob Johnson'}],
        getOptionLabel: ({fullName}) => fullName, // 'fullName' should be inferred from user query
        getOptionValue: ({userId}) => userId
    }
];

The Challenge:

I want each element in the formConfig array to potentially handle a different data type returned by its query function.
For each individual object in the array, the getOptionLabel and getOptionValue callbacks must be strongly typed such that their input parameters (option) correctly reflect the element type T returned by that specific object’s query: () => Promise<T[]> (e.g., for ‘category’, option should be {id: number, categoryName: string}; for ‘user’, option should be {userId: string, fullName: string}).
TypeScript should ideally infer these types without me having to manually specify a generic type for each element or the array itself, maintaining full type safety when accessing properties within the callbacks.

If I define a simple generic interface:

interface FormConfigItem<T> {
    name: string;
    label: string;
    placeholder: string;
    query: () => Promise<T[]>;
    getOptionLabel: (option: T) => string;
    getOptionValue: (option: T) => string | number; // Assuming ID can be string or number
}

Then trying to use it in an array like const formConfig: FormConfigItem[] or FormConfigItem[] loses the specific type information for T within each element, leading to any or unknown for getOptionLabel and getOptionValue parameters, which defeats the purpose of strong typing. Creating a union like (FormConfigItem | FormConfigItem)[] also doesn’t work, as getOptionLabel would then expect CategoryType | UserType, not the specific type for that item.

How can I achieve this dynamic, per-item generic type inference and linkage in TypeScript?

Crud operation using html,css and javascript

I am performing crud operation using html,css and javascript. In this while i m running the web page it’s displaying the form structure but when i am giving the input its not taking or input is not getting saved. how i should resolve this and what mistake am i making there? why my data is not stored ,without storing data i can not perform the crud operation.

var selectedRow = null

function onFormSubmit() {
    if (validate()) {
        var formData = readFormData();
        if (selectedRow == null)
            insertNewRecord(formData);
        else
            updateRecord(formData);
        resetForm();
    }
}

function readFormData() {
    var formData = {};
    formData["fullName"] = document.getElementById("fullName").value;
    formData["empCode"] = document.getElementById("empCode").value;
    formData["salary"] = document.getElementById("salary").value;
    formData["city"] = document.getElementById("city").value;
    return formData;
}

function insertNewRecord(data) {
    var table = document.getElementById("employeeList").getElementsByTagName('tbody')[0];
    var newRow = table.insertRow(table.length);
    cell1 = newRow.insertCell(0);
    cell1.innerHTML = data.fullName;
    cell2 = newRow.insertCell(1);
    cell2.innerHTML = data.empCode;
    cell3 = newRow.insertCell(2);
    cell3.innerHTML = data.salary;
    cell4 = newRow.insertCell(3);
    cell4.innerHTML = data.city;
    cell4 = newRow.insertCell(4);
    cell4.innerHTML = `<a onClick="onEdit(this)">Edit</a>
                       <a onClick="onDelete(this)">Delete</a>`;
}

function resetForm() {
    document.getElementById("fullName").value = "";
    document.getElementById("empCode").value = "";
    document.getElementById("salary").value = "";
    document.getElementById("city").value = "";
    selectedRow = null;
}

function onEdit(td) {
    selectedRow = td.parentElement.parentElement;
    document.getElementById("fullName").value = selectedRow.cells[0].innerHTML;
    document.getElementById("empCode").value = selectedRow.cells[1].innerHTML;
    document.getElementById("salary").value = selectedRow.cells[2].innerHTML;
    document.getElementById("city").value = selectedRow.cells[3].innerHTML;
}
function updateRecord(formData) {
    selectedRow.cells[0].innerHTML = formData.fullName;
    selectedRow.cells[1].innerHTML = formData.empCode;
    selectedRow.cells[2].innerHTML = formData.salary;
    selectedRow.cells[3].innerHTML = formData.city;
}

function onDelete(td) {
    if (confirm('Are you sure to delete this record ?')) {
        row = td.parentElement.parentElement;
        document.getElementById("employeeList").deleteRow(row.rowIndex);
        resetForm();
    }
}
function validate() {
    isValid = true;
    if (document.getElementById("fullName").value == "") {
        isValid = false;
        document.getElementById("fullNameValidationError").classList.remove("hide");
    } else {
        isValid = true;
        if (!document.getElementById("fullNameValidationError").classList.contains("hide"))
            document.getElementById("fullNameValidationError").classList.add("hide");
    }
    return isValid;
}
<table>
    <tr>
        <td>
          <form onsubmit="event.preventDefault();onFormsubmit();" autocomplete="off">
            <div>
            <label>Full Name</label>
            <input type="text" name="fullName">
            </div>
            <div>
               <label>Emp Code</label>
            <input type="text" name="empCode"> 
            </div>
            <div>
                <label>Salary</label>
            <input type="text" name="salary">
            </div>
            <div>
                <label>City</label>
            <input type="text" name="city">
            </div>
            <div class="form-action-buttons">
                <input type="submit" value="Submit">
            </div>
          </form>  
        </td>
        <td>
            <table class="list" id="employeeList">
                <thead>
                    <tr>
                        <th>Full Name</th>
                        <th>EMP Code</th>
                        <th>Salary</th>
                        <th>City</th>
                    </tr>
                </thead>
            </table>
        </td>
    </tr>
</table>