How to get React-Router Route object properties?

From docs: https://reactrouter.com/6.30.1/route/route

Type declaration
interface RouteObject {
  path?: string;
  index?: boolean;
  children?: RouteObject[];
  caseSensitive?: boolean;
  id?: string;
  loader?: LoaderFunction;
  action?: ActionFunction;
  element?: React.ReactNode | null;
  hydrateFallbackElement?: React.ReactNode | null;
  errorElement?: React.ReactNode | null;
  Component?: React.ComponentType | null;
  HydrateFallback?: React.ComponentType | null;
  ErrorBoundary?: React.ComponentType | null;
  handle?: RouteObject["handle"];
  shouldRevalidate?: ShouldRevalidateFunction;
  lazy?: LazyRouteFunction<RouteObject>;
}

How to get id property? I tried using hooks useLocation and
useParams but none showed this property.

UPD: I need to know if the user can edit the data on the page. Along with the user information, accesses to the pages come, for example: [“Page1.FullAccess”,”Pag2.Read”,]

I created:

const Page1Component = lazy(() =>
    import('./page1.ui').then((module) => ({ default: module.Page1 })),
);

const page1Route: RouteObject = {
    id: 'Page1',
path: '/lalala',
    element: createElement(enhance(Page1Component)),
};

AND

const browserRouter = createBrowserRouter(
    [
        {
            errorElement: <BubbleError />,
            children: [
                {
                    element: createElement(enhance(GenericLayout)),
                    children: [
                        page1Route,
                          ...
                    ],
                },
              .....

In the hook that I insert on the page

const useIsCan = () => {
    const location = useLocation();
    const params = useParams();

    const { data, isLoading } = useQuery(getCurrentUserPropsQuery());



const isCanEdit =
    data && data.roles.includes(`${The page ID should be here}.FullAccess`)
    

Why am I not getting Output? [duplicate]

What is the problem in JavaScript
I want to change the background color of the <li> to red .

let li = document.getElementsByTagName("li")
li.forEach(element => {
  element.style.background = "red"
});
<ul class="first">
  <li>Tirth</li>
  <li>Patel</li>
  <li>home</li>
</ul>

Why the JWT over https make the token expired randomly?

I have created a REACT application that calls some REST APIs to get data from a Node.js server.
To enhance security, I am using JWT-based authentication.
It is working properly in the development environment.
In the production environment, I use an HTTPS-protected Apache server as a proxy server to forward requests to my application.

In this environment, I found that the JWT is not working steadily. Sometimes, the application prompts the “JWT expired” message on the server even though the user has logged in.

Here is my server-side code:

let sendResponse = async (res, action, param, jwt, usrObj, headers = {}) => {
try {
    //res.send(await action(param));
    const sanitized = { ...usrObj };
    delete sanitized.iat;
    delete sanitized.exp;
    res.setHeader('x-access-token', jwt.sign(sanitized));
    let result = await action(param);
    if (Object.keys(headers).length === 0) {
        let returnObj = {
            result
        }
        res.send(returnObj);
    } else {
        for (const [key, value] of Object.entries(headers)) {
            res.setHeader(key, value);
        }
        res.send(result);
    }
} catch (error) {
    console.log(error.message);
    res.status(400).send(error.message);
}

}

where “action” is a function that gets data from my database.
The application has an Excel file generation feature, the sendResponse function should support file download.

If I open my application to the internet without the Apache server, it back to normal.

So, what’s going on?

Electron app fails due to GenAI refresh token

I am using google/genai sdk and keep getting the following error.

GaxiosError: invalid_grant
    at Gaxios._request (C:projectstideelectronnode_modulesgaxiosbuildsrcgaxios.js:142:23)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async UserRefreshClient.refreshTokenNoCache (C:projectstideelectronnode_modulesgoogle-auth-librarybuildsrcauthoauth2client.js:212:19)
    at async UserRefreshClient.getRequestMetadataAsync (C:projectstideelectronnode_modulesgoogle-auth-librarybuildsrcauthoauth2client.js:333:17)
    at async UserRefreshClient.getRequestHeaders (C:projectstideelectronnode_modulesgoogle-auth-librarybuildsrcauthoauth2client.js:296:26)
    at async NodeAuth.addGoogleAuthHeaders (C:[email protected]:13617:29)
    at async ApiClient.getHeadersInternal (C:[email protected]:10982:9)
    at async ApiClient.includeExtraHttpOptionsToRequestInit (C:[email protected]:10856:31)
    at async ApiClient.request (C:[email protected]:10805:23)
    at async Models.generateContent (C:[email protected]:12024:24) {
  config: {
    retry: true,
    retryConfig: {
      httpMethodsToRetry: [Array],
      currentRetryAttempt: 0,
      retry: 3,
      noResponseRetries: 2,
      retryDelayMultiplier: 2,
      timeOfFirstRequest: 1748569979920,
      totalTimeout: 9007199254740991,
      maxRetryDelay: 9007199254740991,
      statusCodesToRetry: [Array]
    },
    method: 'POST',
    url: 'https://oauth2.googleapis.com/token',
    data: '<<REDACTED> - See `errorRedactor` option in `gaxios` for configuration>.',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'User-Agent': 'google-api-nodejs-client/9.15.1',
      'x-goog-api-client': 'gl-node/22.15.1'
    },
    paramsSerializer: [Function: paramsSerializer],
    body: '<<REDACTED> - See `errorRedactor` option in `gaxios` for configuration>.',
    validateStatus: [Function: validateStatus],
    responseType: 'unknown',
    errorRedactor: [Function: defaultErrorRedactor]
  },
  response: {
    config: {
      retry: true,
      retryConfig: [Object],
      method: 'POST',
      url: 'https://oauth2.googleapis.com/token',
      data: '<<REDACTED> - See `errorRedactor` option in `gaxios` for configuration>.',
      headers: [Object],
      paramsSerializer: [Function: paramsSerializer],
      body: '<<REDACTED> - See `errorRedactor` option in `gaxios` for configuration>.',
      validateStatus: [Function: validateStatus],
      responseType: 'unknown',
      errorRedactor: [Function: defaultErrorRedactor]
    },
    data: { error: 'invalid_grant', error_description: 'Bad Request' },
    headers: {
      'alt-svc': 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000',
      'cache-control': 'no-cache, no-store, max-age=0, must-revalidate',
      'content-encoding': 'gzip',
      'content-type': 'application/json; charset=utf-8',
      date: 'Fri, 30 May 2025 01:52:59 GMT',
      expires: 'Mon, 01 Jan 1990 00:00:00 GMT',
      pragma: 'no-cache',
      server: 'scaffolding on HTTPServer2',
      'transfer-encoding': 'chunked',
      vary: 'Origin, X-Origin, Referer',
      'x-content-type-options': 'nosniff',
      'x-frame-options': 'SAMEORIGIN',
      'x-xss-protection': '0'
    },
    status: 400,
    statusText: 'Bad Request',
    request: { responseURL: 'https://oauth2.googleapis.com/token' }
  },
  error: undefined,
  status: 400,
  [Symbol(gaxios-gaxios-error)]: '6.7.1'
}

Code that calls it:

const genAI = new GoogleGenAI((apiKey = apiKey));
const response = await genAI.models.generateContent({
        model: "gemini-2.0-flash",
        contents: "test prompt",
      });

I know the key works because I tested it in test.js file

import { GoogleGenAI } from "@google/genai";
const GEMINI_API_KEY = "GEMINI_KEY";

const ai = new GoogleGenAI({ apiKey: GEMINI_API_KEY });

async function main() {
  const response = await ai.models.generateContent({
    model: "gemini-2.0-flash",
    contents: "Why is the sky blue?",
  });
  console.log(response.text);
}

main();

Any idea why this might be happening?

I run the code using npm start which is defined in package.json as:

"scripts": {
    "start": "electron .",
    "build": "electron-builder",
    "test": "echo "Error: no test specified" && exit 1"
  }

Proper algorithm for ltr/rtl mixed text in JavaScript?

I am using the OpenAI completions API to write text like how ChatGPT does it in the user/system message back and forth. But this is for Arabic text, and explanation of text comes back in mixture of English and Arabic sometimes. Is there a standard ideal approach to figuring out how to tell what rtl and ltr mixture you need?

Here I have 4 variants:

  • auto-everywhere: On container, and on each nested span.
  • none-container-mixed-inside: Nothing on container, rtl or ltr on spans (Arabic vs. Latin chunks)
  • rtl-container-mixed-inside: rtl on container, rtl/ltr on spans again
  • rtl-container-auto-inside: rtl on container, auto on all spans

auto-everywhere

none-container-mixed-inside

rtl-container-mixed-inside

rtl-container-auto-inside

General code

<div dir="rtl">
  <p>
    <span dir="auto">بالطبع.</span>
  </p>
  <ul>
    <li>
      <span dir="ltr">"</span>
      <span dir="rtl">الأشجار</span>
      <span dir="ltr">" (al-ashjar) </span>
      <span dir="rtl">تعني </span>
      <span dir="ltr">"trees" </span>
      <span dir="rtl">وهي الفاعل.</span>
    </li>
    <li>
      <span dir="auto">"</span>
      <span dir="auto">جميلة</span>
      <span dir="auto">" (jameela) </span>
      <span dir="auto">تعني </span>
      <span dir="auto">"beautiful" </span>
      <span dir="auto">وهي صفة.</span>
    </li>
    <li>
      <span dir="auto">"</span>
      <span dir="auto">تعطي</span>
      <span dir="auto">" (tu'ti) </span>
      <span dir="auto">تعني </span>
      <span dir="auto">"give" </span>
      <span dir="auto">وهي الفعل.</span>
    </li>
    <li>
      <span dir="auto">"</span>
      <span dir="auto">الحياة</span>
      <span dir="auto">" (al-hayat) </span>
      <span dir="auto">تعني </span>
      <span dir="auto">"life" </span>
      <span dir="auto">وهي المفعول الأول.</span>
    </li>
    <li>
      <span dir="auto">"</span>
      <span dir="auto">الظل</span>
      <span dir="auto">" (al-zill) </span>
      <span dir="auto">تعني </span>
      <span dir="auto">"shade" </span>
      <span dir="auto">وهي المفعول الثاني.</span>
    </li>
  </ul>
  <p>
    <span dir="auto">الجملة تصف جمال الأشجار وقدرتها على إعطاء الحياة والظل.</span>
  </p>
  <p>
    <span dir="auto">هل هذا يوضح ما كنت تتساءل عنه؟</span>
  </p>
</div>

Copied Content

For readability’s sake, here is the plain text:

بالطبع.

"الأشجار" (al-ashjar) تعني "trees" وهي الفاعل.
"جميلة" (jameela) تعني "beautiful" وهي صفة.
"تعطي" (tu'ti) تعني "give" وهي الفعل.
"الحياة" (al-hayat) تعني "life" وهي المفعول الأول.
"الظل" (al-zill) تعني "shade" وهي المفعول الثاني.
الجملة تصف جمال الأشجار وقدرتها على إعطاء الحياة والظل.

هل هذا يوضح ما كنت تتساءل عنه؟

Question

Seems like a difficult potentially ambiguous/unsolvable problem, but thought I’d ask anyways.

  • How can you tell what is the main text there to format the overall direction with?
  • What would you recommend be done?

I feel like it could get quite ambiguous. For example, take these strings:

# should be rtl
هل هذا يوضح ما كنت تتساءل عنه
# ltr
it could get quite ambiguous
# ltr
it could get تتساءل quite ambiguous
# rtl
هل هذا يوضح ما hello كنت تتساءل عنه
# rtl
hello هل هذا يوضح ما كنت تتساءل عنه

So it seems you would have to know the meaning of the sentence to figure this out properly.

Is there any automatic way to do this nicely?

If not, do you think it’s possible to get ChatGPT to send me each line as JSON perhaps, and tell me? I guess that could work.

Or is there a JavaScript algorithm I could implement to solve this somehow?

I am already parsing each chunk of text (arabic vs. latin) into spans, like this pretty much:

export type Span = {
  fontSize: number
  script: string
  // heading: number
  text: string
  count: number
  heading: number
  dir?: 'ltr' | 'rtl'
}

export function parseSpans(text, size) {
  const spans = []
  const span = []
  const list = [...text]
  let script

  function add(span, script) {
    const heading = FONT_SIZE_MULTIPLIERS[script ?? 'code']?.body ?? 1
    const fontSize = Math.round(size * heading)
    const dir = getScriptDirection(script ?? 'latin')

    spans.push({
      fontSize,
      dir: 'auto',
      count: span.length,
      script:
        !script || script === 'latin'
          ? 'code'
          : script === 'other'
            ? 'code'
            : script,
      heading,
      text: span.join(''),
    })
  }

  for (const char of list) {
    const type = detectSymbol(char)

    if (!type || type === script) {
      span.push(char)

      script = type
    } else if (char.match(/[s.,:;{}[]()-?!]/)) {
      span.push(char)
    } else {
      add(span, script)

      span.length = 0

      span.push(char)

      script = type
    }
  }

  if (span.length) {
    add(span, script)
  }

  return spans
}

So maybe I can expand that or something. Looking for advice on either a specific algoritm or a “there’s nothing you can do in this situation” type answer.

How can I bypass CORS for a frontend-only JavaScript app accessing a Philippine government API?

I’m building a frontend-only web version of the Bureau of Customs – Bond Inquiry System using HTML, Bootstrap, and vanilla JavaScript. The goal is to:

Fetch a JWT token via a POST request using a username and password.

Use that token to retrieve bond data via a GET request and display it in a Bootstrap DataTable.

Allow users to export the data to Excel.

However, when I try to call the API from the browser, I get a CORS error:
Access to fetch at ‘https://oms-api.customs.gov.ph/token’ from origin ‘null’ has been blocked by CORS policy:
No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

Since this is a frontend-only project, and I cannot modify the server’s headers (it’s a government server), how can I bypass the CORS restriction securely?

What Works
The API works perfectly in Postman using the same credentials and endpoints.

I receive the token and fetch data without issue outside the browser.

Here’s the JavaScript I’m using to get the token and data (simplified):

const tokenURL = 'https://oms-api.customs.gov.ph/token';
const dataURL = 'https://oms-api.customs.gov.ph/entry_code';

const username = 'cosmo_tick_app';
const password = 'MulaDaungan.HanggangPaliparan2025';

let accessToken = '';

async function getAccessToken() {
  try {
    const response = await fetch(tokenURL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ username, password })
    });

    const data = await response.json();
    accessToken = `${data.token_type} ${data.access_token}`;
  } catch (error) {
    console.error('Failed to get access token', error);
  }
}

Modal function only work once when button is clicked from the page and needs a page refresh to make it work again

Good day! I need help/suggestion on how to resolve the issue I am having. What happens is that the modal or warning message when button is clicked only work one time when page load. After that, when you click the button again, the expected behavior for the modal/warning message to show up does not work. I need to refresh the page to make the function work.

Sending the sample code I am working on. Thank you for the assist.

(function () {
'use strict';

const allowedTitles = [
    "Test1",
    "Test2",
    "Test3"
    
];

const blockedStatuses = [
    "Test4",
    "Test5",
    "Test6"        
];

function isValidPage() {
    return allowedTitles.some(title => document.title.includes(title));
}

function isBlockedStatus() {
    const statusHeader = document.getElementById("test_header");
    if (!statusHeader) return false;
    return blockedStatuses.some(status => stattatusHeader.textContent.includes(status));
}

function createModal() {
    let modal = document.getElementById("customConfirmationModal");

    if (!modal) {
        modal = document.createElement("div");
        modal.id = "customConfirmationModal";
        modal.style.cssText = `
            position: fixed; top: 0; left: 0; width: 100%; height: 100%;
            background: rgba(0,0,0,0.5); display: flex;
            align-items: center; justify-content: center;
            z-index: 99999;
        `;

        modal.innerHTML = `
            <div style="background: white; padding: 20px; border-radius: 8px; width: 400px;    


        max-width: 90%;">
                <h3 style="margin-top: 0;">Confirmation Required</h3>
                <p>Do you want to proceed?</p>
                <div style="text-align: right;">
                    <button id="cancelModalBtn" style="margin-right: 10px;">Cancel</button>
                    <button id="proceedModalBtn" style="background-color: #0073bb; color: 
    white; border: none; padding: 6px 12px; border-radius: 4px;">Proceed</button>
                </div>
            </div>
        `;
        document.body.appendChild(modal);
    }

    modal.style.display = "flex";

       document.getElementById("cancelModalBtn").onclick = () => {
        modal.style.display = "none";
    };

    document.getElementById("proceedModalBtn").onclick = () => {
        modal.style.display = "none";
        const realBtn = document.getElementById("testbtn");
        if (realBtn) {
            realBtn.dataset.skipIntercept = "true";
            setTimeout(() => realBtn.click(), 0);
        }
    };
}

function handleButtonClick(e) {
    const btn = e.currentTarget;
    if (btn.dataset.skipIntercept === "true") {
        btn.dataset.skipIntercept = "false";
        return;
    }
    e.preventDefault();
    e.stopPropagation();
    createModal();
}

function setupButton() {
    const btn = document.getElementById("testbtn");
    if (!btn || btn.dataset.intercepted === "true") return;

    if (isValidPage() && !isBlockedStatus()) {
        btn.dataset.intercepted = "true";
        btn.addEventListener("click", handleButtonClick, true);
    }
}

const observer = new MutationObserver(() => {
    setupButton();
});

observer.observe(document.body, {
    childList: true,
    subtree: true
});

// Initial setup
setupButton();

})();

Next.js generateMetadata not applying correctly with conditional rendering in layout – metadata only loads after hot reload

I’m working on a multi-tenant Next.js application where I’m experiencing an issue with metadata generation. When a valid subdomain exists and the tenant is found, everything works perfectly – the app renders and metadata is applied correctly. However, when the tenant validation fails and conditional rendering is triggered, the metadata for the invalid tenant doesn’t load unless I make a code change that triggers Next.js hot reload – only then does the metadata appear. (Please be nice, I’m new in Nextjs lmao)

layout.tsx:

import type { Metadata } from "next";

import "./globals.css";
import { getTenantData } from "@/lib/utils";
import MissingSubdomainError from "@/components/errors/MissingSubdomainError";
import InvalidTenantError from "@/components/errors/InvalidTenantError";
import { TenantProvider } from "@/components/providers/tenant-provider";

export async function generateMetadata(): Promise<Metadata> {
  const { subdomain, tenant } = await getTenantData();

  if (!subdomain) {
    return {
      title: "Subdominio no definido",
      description: "No se proporcionó un subdominio válido",
    };
  }

  if (!tenant) {
    return {
      title: "Tenant inválido",
      description: `No se encontró ningún tenant llamado "${subdomain}"`,
    };
  }

  return {
    title: tenant.name,
    description: `Sitio de ${tenant.name}`,
  };
}

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const { subdomain, tenant } = await getTenantData();

  if (!subdomain) return <MissingSubdomainError />;
  if (!tenant) return <InvalidTenantError subdomain={subdomain} />;

  return (
    <html lang="es">
      <body>
        <TenantProvider subdomain={subdomain} tenantData={tenant}>
          {children}
        </TenantProvider>
      </body>
    </html>
  );
}

InvalidTenantError.tsx:

export default function InvalidTenantError({
  subdomain,
}: {
  subdomain: string;
}) {
  return (
    <html lang="es">
      <body className="flex items-center justify-center min-h-screen bg-gray-100">
        <div className="bg-white p-8 rounded-xl shadow-lg text-center max-w-md">
          <h1 className="text-3xl font-bold text-red-600 mb-4">
            Subdominio inválido
          </h1>
          <p className="text-gray-700 mb-2">
            El subdominio{" "}
            <span className="font-semibold text-gray-900">{subdomain}</span> no
            está registrado.
          </p>
          <p className="text-gray-600 mb-4">
            Verifica que lo hayas escrito correctamente. Por ejemplo:
          </p>
          <code className="bg-gray-100 px-2 py-1 rounded text-sm text-gray-800">
            empresa.localhost
          </code>
          <p className="text-sm text-gray-500 mt-4">
            Si crees que esto es un error o necesitas ayuda, contáctanos.
          </p>
        </div>
      </body>
    </html>
  );
}

utils.ts:

import { headers } from "next/headers";
import { prisma } from "./prisma";

export async function validateTenant(subdomain: string) {
  try {
    const tenant = await prisma.tenant.findUnique({
      where: {
        subdomain: subdomain,
        active: true,
      },
    });

    return tenant;
  } catch (error) {
    console.error("Error validating tenant:", error);
    return null;
  }
}

export async function getTenantData() {
  const headersList = await headers();
  const subdomain = headersList.get("x-tenant");

  if (!subdomain) {
    return { subdomain: null, tenant: null };
  }

  const tenant = await validateTenant(subdomain);
  return { subdomain, tenant };
}

package.json:

{
  "name": "tenanttest",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev --turbopack",
    "build": "prisma generate && next build",
    "start": "next start",
    "lint": "next lint",
    "db:seed": "tsx prisma/seed.ts"
  },
  "dependencies": {
    "@prisma/client": "^6.8.2",
    "next": "15.3.2",
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    "zustand": "^5.0.5"
  },
  "devDependencies": {
    "@eslint/eslintrc": "^3",
    "@tailwindcss/postcss": "^4",
    "@types/node": "^20",
    "@types/react": "^19",
    "@types/react-dom": "^19",
    "eslint": "^9",
    "eslint-config-next": "15.3.2",
    "prisma": "^6.8.2",
    "tailwindcss": "^4",
    "tsx": "^4.19.4",
    "typescript": "^5"
  }
}

Metadata working

Metadata not working

Angular inject() vs DI

When injecting a service in Angular what could be more optimized? Constructor-Based Dependency Injection or Inject?
I have the perception that inject is more optimized, because when we choose this path over the constructor one, due to the behavior of native class fields in JavaScript they are initialized before the constructor runs, an example:

private service = inject(Service);
private get = this.service.get;

Is this correct? Or is my perception of the behavior under the hood wrong?

JavaScript’s sync code inside async method

I have some code in Node.js.

Is there any risk that result.map(...) won’t finish before the promise resolves, especially with a large dataset?

My code reviewer said I should wrap it like this await Promise.resolve(result.map(....))

public static async getBankOrders(): Promise<IPaymentBankOrderDocumentStruct[]> {
        const params = this.getCriteria();
        const promises = [mongoDb.collection_1, mongoDb.collection_2, mongoDb.collection_3].map(async el => await this.getOneBankOrderList(el, params));

        return (await Promise.all(promises)).flat();
    }

private static async getOneBankOrderList(collection: string, params: RequestParamsInterface): Promise<IPaymentBankOrderDocumentStruct[]> {
        const result = (await new Request(collection as any).getList(params)).data as BankOrderDocumentStruct[];

        return result.map(el => ({ ...el, collection }));   
    }

Setting an initial address for Google Places PlaceAutocompleteElement

Since Google deprecated its old places autocomplete API in March 2025, we’ve been converting to the newer API.

We had a use case with a requirement to set the initial value of Google’s “New” Places PlaceAutocompleteElement

It doesn’t look like Google supports that functionality.

This is more a solution then a question. I’m posting it because I didn’t see an answer anywhere on line, and spent a bit of time figuring it out. If anyone has a better solution please post.

This is the code I finally got working.

<html>
<head>
    <meta charset="utf-8" />
    <title>Initial Google PlaceAutocompleteElement</title>
    <script>
        (g => { var h, a, k, c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(" could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })
            ({ key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", v: "weekly" });</script>

    <style type="text/css">
        #myWrapper {
            width: 800px;
            height: 400px;
            background-color: #ddf;
            padding: 1em;
            border: 2px solid #1d4969
        }

        #container {
            width: 700px;
            height: 60px;
        }

            #container pre {
                max-height: 300px;
            }

            #container .widget-container {
                height: 100px;
            }
        h4 { margin-top:60px; }
    </style>
</head>
<body>
    <div id="myWrapper">
        <div id="container">
            <h3>Search for a place:</h3>
        </div>
        <h4>Result:</h4>
        <pre class="results"></pre>
    </div>

    <script type="text/javascript">
        "use strict";
        /*
         * @license
         * Copyright 2025 Google LLC. All Rights Reserved.
         * SPDX-License-Identifier: Apache-2.0
         */

        // https://developers.google.com/maps/documentation/javascript/place-autocomplete-new
        // Based on  https://jsfiddle.net/gh/get/library/pure/googlemaps-samples/js-api-samples/tree/main/dist/samples/place-autocomplete-element/jsfiddle

        async function initMap() {
            // Request needed libraries
            await google.maps.importLibrary("places");

            // Create the input HTML element
            const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement();

            // Get the container element and append the autocomplete
            const containerElem = document.getElementById('container');
            containerElem.appendChild(placeAutocomplete);

            // Add the gmp-placeselect listener, and display the results
            placeAutocomplete.addEventListener('gmp-select', async ({ placePrediction }) => {
                const place = placePrediction.toPlace();
                await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'] });

                // Update results
                document.querySelector('pre.results').textContent =
                    JSON.stringify(place.toJSON(), /* replacer */ null, /* space */ 2);
            });
        }

        // Finds and sets input field inside div#container gmp-place-autocomplete
        function setMapInput(theLocation) {
            // Find the custom element google mapping element
            const customElement = document.querySelector('#container gmp-place-autocomplete');

            if (!customElement) {
                console.log('gmp-place-autocomplete not found in #container');
                return;
            }

            // "Og" is the dom element created by Google Maps PlaceAutocompleteElement that contains the input field we want to update.
            // Hopefully this does not change.
            const inputField = customElement.Og.querySelector('input');
            if (inputField) {
                inputField.value = theLocation;

                // Trigger an input event for potential listeners if you want to show the suggestions
                // const inputEvent = new Event('input', { bubbles: true });
                // inputField.dispatchEvent(inputEvent);
            }
        }

        // Page loaded
        document.addEventListener('DOMContentLoaded', function () {
            // Start map initialization
            initMap()
                .then(() => {
                    setMapInput('2401 Ontario Street Cleveland');
                })
                .catch(error => {
                    console.error("Error initializing map:", error);
                });
        });

    </script>
</body>
</html>

How to delete elements which have no parent?

When creating elements with the var keyword without assigning them to a parent node/element in HTML, they will be stored in the window object. But how to delete such elements from the window object to prevent flooding the memory?

Example:

var myElm = document.createElement('a');

Deleting it with the delete keyword doesn’t seem to work (no error is thrown by JS and the attribute/reference remains in the window object):

delete window.myElm;

Does it mean that using var will create elements which cannot be deleted anymore (if not assigned to any parent element) and let should always be used in the declaration instead?

How to delete elements which has no parent?

When creating elements with the var keyword without assigning them to a parent node/element in HTML, they will be stored in the window object. But how to delete such elements from the window object to prevent flooding the memory?

Example:

var myElm = document.createElement('a');

Deleting it with the delete keyword doesn’t seem to work (no error is thrown by JS and the attribute/reference remains in the window object):

delete window.myElm;

Does it mean that using var will create elements which cannot be deleted anymore (if not assigned to any parent element) and let should always be used in the declaration instead?