Google Maps Route Disappears on Page Refresh Despite Persisted State

I’m developing a real-time tracking application using ASP.NET Core with SignalR and the Google Maps JavaScript API. My app displays markers and a computed route on the map that connects two types of users. The marker color changes (for example, red for inactive, yellow for active, purple for cancelled) based on flags that are stored in my own database.

The expected behavior is that when a user refreshes the page, the map should be rebuilt exactly as it was before the refresh using only the persisted database state. In practice, after a refresh, although the marker positions are restored, the computed route disappears and, in one scenario, a marker that was previously showing as yellow reverts to red—even though the database still indicates an active state.

The controller is sending the current flag values (e.g., for an active trip) and stored locations via ViewBag.

I force the persisted flag values to lowercase before comparing them in my JavaScript.

My client-side logic correctly computes the route when the page loads in initial tests, but after a refresh the route no longer appears even though the stored values are intact.

I attempted to persist the displayed route and marker colors on my Google Maps dashboard by relying solely on state saved to my own database. In my ASP.NET Core controllers, I pass persisted values for the student’s active trip, cancelled trip, and the driver’s last location via the ViewBag. Then, in my Razor view’s JavaScript, I force these boolean flags to lowercase and compare them to “true” in order to decide which marker icon to display. For example, in my student dashboard, I initialize the flag like this:

var studentActiveTrip = ('@(ViewBag.StudentActiveTrip != null ? ViewBag.StudentActiveTrip.ToString().ToLower() : "false")' === 'true');
var studentCancelledTrip = ('@(ViewBag.StudentCancelledTrip != null ? ViewBag.StudentCancelledTrip.ToString().ToLower() : "false")' === 'true');

Later, when initializing the map, I check these flags to determine the correct marker color:

if (storedLat && storedLng) {
  let lat = parseFloat(storedLat);
  let lng = parseFloat(storedLng);
  let pos = { lat: lat, lng: lng };
  map.setCenter(pos);
  map.setZoom(posZoom);
  
  // Determine which icon to display based on the persisted state.
  let iconUrl = "http://maps.google.com/mapfiles/ms/icons/red-dot.png";
  if (studentActiveTrip) {
    iconUrl = "http://maps.google.com/mapfiles/ms/icons/yellow-dot.png";
    window.tripActive = true;
  } else if (studentCancelledTrip) {
    iconUrl = "http://maps.google.com/mapfiles/ms/icons/purple-dot.png";
    window.tripActive = false;
  }
  
  window.studentMarker = new google.maps.Marker({
    position: pos,
    map: map,
    icon: iconUrl
  });
}

Even though my controller is sending the correct state (for example, ActiveTrip is true), when I refresh the page the student’s marker reverts to red and the computed route disappears—despite the fact that the data in the database remains unchanged.

I expected that on a refresh the map would be rebuilt exactly as it was before, so that if ActiveTrip is true in the database the student’s marker would remain yellow and the route between the student and the driver (if the driver’s location is available) would be re-calculated and displayed.

Why is the second character missing and an undefined character added in my typing effect?

I’m working on a simple typing effect component in React using Framer Motion. Here’s the code for my TypingText component

TypingText.jsx

import { motion } from 'framer-motion';
import React, { useEffect, useState } from 'react';

const TypingText = ({ text, speed = 100 }) => {
  const [displayedText, setDisplayedText] = useState('');

  useEffect(() => {
    if (!text) return;
    let i = 0;
    const interval = setInterval(() => {
      setDisplayedText((prev) => prev + text[i]);
      i++;

      if (i >= text.length) clearInterval(interval);
    }, speed);

    return () => clearInterval(interval);
  }, [text, speed, setDisplayedText]);

  return (
    <motion.div className="font-mono text-2xl">{displayedText}</motion.div>
  );
};

export default TypingText;

Home.jsx
<TypingText text="Hi, I am Thulhid" />

Output: H, I am Thulhidundefined

The second character (“i”) is missing.

An undefined appears at the end.

and I changed the code inside the interval like this:

 const char = text[i];
  setDisplayedText((prev) => prev + char);

With this change, it works as expected. But now I’m confused:

Why does accessing text[i] directly inside the setDisplayedText callback cause this issue?

Why does extracting it into a separate variable (char) solve the problem?
I want to know why this happen?

Any explanation around JavaScript closures, async behavior, or how i is captured in state updates would be super helpful.

Protecting HTML DOM attributes from DEV tools

I need to be able to store protected, DOM element, attributes at the UI. (For example, I want to store the DBKEY of the target database row along side the matching table row.)

As I can see no way of locking the DATA- attributes down to prevent user manipulation, I am in need of a viable alternative.

The freeze() method is only available at the Object/Element level, so the next thing that comes to mind is a minimal virtual DOM (or two-way binding) but virtualDOM are anathema to me, and surely there must be another way to do this.

So, I can keep and maintain a nodeList of DOM Elements and mutations on my current pagelet/DIV and add/modify as many protected attributes as I like. Resulting in sequential searches of the nodeList +/- making the index available to Javascript.

Or B, create a mirror, unattached DOM tree create/node, appendChild etc. But closest() is good but I know of no built-in down-tree search.

Anyway, I’ve got to be over thinking this? Is there a simple way to supply a read-only attribute to a DOM element?

DOM Elements only generating after using the inspect-element tool on chrome/firefox

I’m trying to create a script that automatically plays a video whenever it’s paused on a third party website. The issue I’m having is that the HTML elements in the page seem to be generated only as I inspect each line of code.

As an example:
document.querySelector('video')

returns “null” at first, but after using the inspect-element tool, and moving to the lines, I can get the very same JavaScript code to return the video player element, which is very perplexing honestly

The issue is the same for both Chrome and Firefox.

I tried various AI-suggested approaches to generate all the DOM via JavaScript but to be frank, I think the matter to be outside the scope of my expertise, I don’t feel competent to summarize all the things that I tried to the extent that I wouldn’t maybe mislead someone trying to help

I can confidently say that the DOM generation isn’t triggered by other means such as moving the mouse/scrolling/resizing

How to make a copy of a function in javascript

In javascript, I want to make a (shallow) copy of a Function, so that the properties of the new object will not be affected by the original object:

function func(...) { ... } // to say, function func(x, y) { return [x,y] }
func.a = 1
let func1 = func       // without copy, func1 and func IS the same object
let func2 = copy(func) // need to be implemented

func.a = 2
func1.a        // becomes 2
func2.a        // shall still be 1
func2("abc")   // shall return the same result as func("abc")

Is it possible?


The best way I’ve found at present is defining a wrapper function:

function f0(x, y) { return [x,y] }
f0.a = 1

function copy(fn){
  function wrapper(){
    return fn.apply(wrapper, arguments)
  }
  Object.assign(wrapper,fn)
  return wrapper
}

let f2 = copy(f0)

f0.a = 2
f2.a        // is still 1
f0.length   // gives 2
f2.length   // gives 0

However, there are some problems with this solution:

  1. Chain appling of copy will lead to multiple levels of wrapper. for example, copy(copy(copy(fn))) will return a function with three wrappers.
  2. the length of the origin function is lost, wrapper.length is alaways 0.

Processing multiple .csv files in Google Apps Script

I’ve been working on a process of batch importing the data from multiple .csv files on my computer into Google Sheets without uploading all of them to Google Drive first.

I currently have the following:

index.html

<form>
  <input type="file" name="file" onchange="importCsv(this.parentNode)" accept=".csv,text/csv" multiple>
</form>
<p id="progress" style="display:none;">
  <label for="upload" style="font-family: sans-serif;">Uploadling...</label>
  <progress id="upload"></progress>
</p>
<script>
  function readFileAsBuffer(file){
    return new Promise(function(resolve,reject){
      let fr = new FileReader();

      fr.onload = function(){
          resolve(fr.result);
      };

      fr.onerror = function(){
          reject(fr);
      };

      fr.readAsArrayBuffer(file);
    });
  }
  async function importCsv(e) {
    document.getElementById("progress").style.display = "block";
    const files = e.file.files;
    let fileReaders = [];
    let fileValues = [];

    for(let i = 0;i < files.length;i++){ 
      fileReaders.push(readFileAsBuffer(files[i])); 
    }

    await Promise.all(fileReaders).then((values) => {
      fileValues.push(values);

    });

    for(let i=0; i < files.length; i++)
    {
      let file = files[i];
      await google.script.run.withSuccessHandler(google.script.host.close).importCsv([[...new Int8Array(fileValues[0][i])], file.type, file.name]);
    }    
  }
</script>

script.gs

function onOpen() {
  SpreadsheetApp.getUi().createMenu("Import").addItem("Import CSVs", "importCsv").addToUi();
}

function importCsv(e){
  if (!e) {
    SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutputFromFile("index"), "Import CSVs");
    return;
  }
  const lock = LockService.getScriptLock();
  lock.waitLock(30000);
  const csv = Utilities.parseCsv(Utilities.newBlob(...e).getDataAsString());
  const sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange(sheet.getLastRow() + 3, 1, csv.length, csv[0].length).setValues(csv);
  lock.releaseLock();
}

I initially had it set up not using promises, but I was finding that all of the files I tried to import would get placed into the spreadsheet out of order. I thought that by using promises to wait until each file was read and processed before passing over to the spreadsheet would help with this, but I’m still running into the same issue. Other than using the LockService object like I’m doing, does anyone have any ideas on how to make the script wait until each section is finished getting added to the spreadsheet?

Thanks!

How to override rem for Shadow DOM?

I’m developing a Chrome browser extension. In Vuetify (as well as in PrimeVue, MUI, and almost any other UI library), component font sizes are defined in rem. When integrating the library into a shadow DOM element, the rem value set within the shadow DOM’s HTML is ignored in favor of the rem from the root HTML element. This results in varying font sizes across different websites, depending on the font-size of the root HTML element. What is the best way to address this issue? Should I attempt to override the styles in the UI library, or is there another method to force the UI library to use the rem defined in the shadow DOM instead of that from the root HTML element?

This dropdown button has no onclick event for expanding. Couldn’t figure out how to expand it via keyboard shortcut [duplicate]

How can I expand this dropdown via keyboard shortcut?

https://imgur.com/a/AFU1ad6 console v1

https://imgur.com/a/phk01OI console v2

https://imgur.com/a/OLFSYDo This button’s onclick is also null.

// ==UserScript==
// @name         TEST CLAUDE: share chat v2
// @match        https://claude.ai/*
// ==/UserScript==

(function() {
    'use strict'

    document.addEventListener('keydown', function(event) {
        let BTN = document.querySelector(".right-3\.5") // DROPDOWN ARROW
        if (BTN) {
            console.log("success: found button");
            BTN.click() // Can't do this. "Uncaught TypeError: BTN.click is not a function" because onclick is null
        } else {
            console.log("error: not found button");
        }
    })
})()

unable to open a doPostBack javascript link- Help please

I need to pay my electric bill and sometimes CFE (Mexican electric company) glitches out so I can’t view past or current pdfs. When I click the link it gives me this javascript address but won’t open. Not sure if it’s possible to get any help but figured I’d give it a shot!

javascript:__doPostBack(‘ctl00$MainContent$gvFacturasUsuario$ctl03$lnkDescargaPDF’,”)

I have attempted opening in various browsers and on different devices to no avail. I really don’t know what I’m doing to be honest.

How can I securely hide my API key in front-end JavaScript? [duplicate]

I’m working on a project using JavaScript for the front end, and I need to use an API key to access a third-party service. However, I understand that including the API key directly in the front-end code (e.g., in a JavaScript file) is insecure because it can be exposed to anyone who inspects the source code.
I’ve researched some solutions like using environment variables, but I can’t figure out how to implement this securely in the context of a front-end application.
Here are my questions:

  • What are the best practices for securing an API key in a front-end application?
  • Are there any examples of how to handle this?
  • Is there a way to hide the API key completely, or is that only possible on the server side?

Thanks in advance for your help!

Import JS function from another file doesnt work

im doing a little project for my own to my portfolio. Im a beginner programmer and i have a problem with import function js from another file. This function is necessary because i need this to use in another logic of my code. These two files are in the same folder named scripts. Scripts are added to index.html before the body closing tag with defer attibute.

ProductsDb.mjs:

import axios from "axios";

const productsDb = process.env.DB_BASE_URL;
let products;

export const fetchProducts = async () => {
  const productsDb = process.env.DB_BASE_URL;
  try {
    const res = await axios.get(productsDb);
    products = res.data;
    //console.log("value of products:", products);
    return products;
  } catch (err) {
    console.err("Error fetching products: ", err);
    throw err;
  }
};
const createProductCart = async () => {
  await fetchProducts();
  const shopList = document.querySelector(".shop-list");
  shopList.innerHTML = "";
  console.log(products);

  products.forEach((element) => {
    const shoppingCart = document.createElement("li");
    shoppingCart.classList.add("shop-list-item");

    let imgURL = `http://127.0.0.1:3000${element.image}`;
    shoppingCart.innerHTML = `
        <a href="#">
          <img class="item-image" height="320px" width="320px" src="${imgURL}" alt="${element.name}" />
          <div class="shop-list-info">
            <p>${element.category}</p>
            <h3>${element.name}</h3>
          </div>
        </a>
        <button class="openCartModal" data-id="${element.id}">Wybierz opcje</button>
      `;

    shopList.appendChild(shoppingCart);
  });
  return;
};

document.addEventListener("DOMContentLoaded", async () => {
  try {
    createProductCart();
  } catch (err) {
    console.error("Error", err);
  }
});

modal.mjs:

import { fetchProducts } from "./productsDb.mjs";

// Open quick shopping modal window
const shopList = document.querySelector(".shop-list");
shopList.addEventListener("click", function (ev) {
  const modal = document.querySelector("[modalOpen]");
  const modalClose = document.querySelector("[modalClose]");

  if (ev.target.closest(".openCartModal")) {
    openModal(modal, modalClose);
  }
});

function openModal(modal, modalClose) {
  modal.classList.toggle("isHidden");

  function close() {
    modal.classList.toggle("isHidden");
    document.removeEventListener("keydown", keyClose);
    modal.removeEventListener("click", clickOutClose);
    modalClose.removeEventListener("click", close);
  }

  function keyClose(ev) {
    if (ev.key === "Escape" && !modal.classList.contains("isHidden")) {
      close();
    }
  }

  function clickOutClose(ev) {
    if (ev.target === modal || ev.target.classList.contains("isHidden")) {
      close();
    }
  }
  document.addEventListener("keydown", keyClose);
  modal.addEventListener("click", clickOutClose);
  modalClose.addEventListener("click", close);
}

I need to use the fetchProducts function in modal logic to pass value from database to the opening modal. Im trying change my script type to module, also in package.json changing type to module but with no positive results.
When Im restarting my frontend only the name of error in console changing every each of time.

I receive that something like that: https://imgur.com/WteeLC2

Any ideas will be very helpful for me.