Variable containing string is undefined when using it with Puppeteer,

I’m attempting to scrape a website using puppeteer and that requires me to fill in a date field with the date a week from when its executed. I used a date object to get the date a week in the future then created 3 constants (changed to variables for troubleshooting), and tried to use page.$eval to fill the date field. However whenever page.$eval runs it throws an error saying the variables are undefined.

I’ve tried swapping constant’s for variables, console logging the variables (which log correctly), swapping the order of the variables within $eval.

Below is the code:

  const pageToday = await page.content();
  const weekAway = new Date(Date.now() + 604800000);
  var wYear = weekAway.getFullYear();
  var wMonth = (weekAway.getMonth() + 1).toString().padStart(2, "0");
  var wDay = weekAway.getDate().toString().padStart(2, "0");
  console.log(wMonth, wYear, wDay);
  await page.$eval(
    "#ctl00_cp_dtbDate",
    (el) => (el.value = `${wMonth}/${wDay}/${wYear}`),
  );
  const pageWeek = await page.content();
  await browser.close();

The target html element is: <input type="date" id="ctl00_cp_dtbDate" name="ctl00$cp$dtbDate" value="2024-10-22" class="" size="11" style="width:110px;" data-dashlane-rid="cf2be948f7a04438" data-dashlane-classification="date">

and here is the error:

node:internal/process/promises:394
    triggerUncaughtException(err, true /* fromPromise */);
    ^

Error [ReferenceError]: wMonth is not defined
    at $eval ($eval at /Users/nikolai/Developer/Digital Tech/daymap/server/server.js:167:14, <anonymous>:0:24)
    at #evaluate (/Users/nikolai/Developer/Digital Tech/daymap/server/node_modules/puppeteer-core/lib/cjs/puppeteer/cdp/ExecutionContext.js:386:56)
    at async ExecutionContext.evaluate (/Users/nikolai/Developer/Digital Tech/daymap/server/node_modules/puppeteer-core/lib/cjs/puppeteer/cdp/ExecutionContext.js:273:16)
    at async IsolatedWorld.evaluate (/Users/nikolai/Developer/Digital Tech/daymap/server/node_modules/puppeteer-core/lib/cjs/puppeteer/cdp/IsolatedWorld.js:99:16)
    at async CdpJSHandle.evaluate (/Users/nikolai/Developer/Digital Tech/daymap/server/node_modules/puppeteer-core/lib/cjs/puppeteer/api/JSHandle.js:142:20)
    at async CdpElementHandle.evaluate (/Users/nikolai/Developer/Digital Tech/daymap/server/node_modules/puppeteer-core/lib/cjs/puppeteer/api/ElementHandle.js:337:20)
    at async CdpElementHandle.$eval (/Users/nikolai/Developer/Digital Tech/daymap/server/node_modules/puppeteer-core/lib/cjs/puppeteer/api/ElementHandle.js:491:24)
    at async CdpFrame.$eval (/Users/nikolai/Developer/Digital Tech/daymap/server/node_modules/puppeteer-core/lib/cjs/puppeteer/api/Frame.js:444:20)
    at async CdpPage.$eval (/Users/nikolai/Developer/Digital Tech/daymap/server/node_modules/puppeteer-core/lib/cjs/puppeteer/api/Page.js:447:20)
    at async /Users/nikolai/Developer/Digital Tech/daymap/server/server.js:167:3

Handling 5000 API Calls per Second in a Financial/Trading App – Seeking High Performance Solution [closed]

I am working on a Node.js-based financial/trading app where the system needs to handle scenarios like placing 5000 API calls in a second. These can be the same or different APIs. I want to process all these requests in parallel with a high response time and low latency.

What would be the best approach for optimizing Node.js to handle such a high volume of parallel API calls? I’m looking for a solution that ensures low latency and fast responses. Any guidance or suggestions would be highly appreciated

Here’s what I’ve tried so far:

Implemented Node.js clustering to leverage all CPU cores.
Used worker threads for parallel task execution.
Conducted load testing using Artillery at 500-1000 requests per second (RPS).
Despite these efforts, I’m facing issues with timeouts and high response times, particularly under load.

How to handle multiple asynchronous API requests while ensuring the order of the final output in JavaScript?

I’m working on a JavaScript project where I need to fetch data from multiple APIs asynchronously. Since each API call takes different amounts of time, I want to ensure that the final output array maintains the same order as the original API request sequence.

Problem:

  • I need to make multiple asynchronous API calls in parallel to improve performance.
  • The results must appear in the same order as the requests were made, even though each API takes a different time to respond.

For example, if I request data from three APIs in this order:

const urls = ['api/1', 'api/2', 'api/3'];

Even though api/2 may finish before api/1, the final output should still have the results in the order: ['result from api/1', 'result from api/2', 'result from api/3'].

I attempted to use Promise.all() to fetch the data:

const urls = ['api/1', 'api/2', 'api/3'];

const fetchData = async () => {
  const promises = urls.map(url => fetch(url).then(response => response.json()));
  const results = await Promise.all(promises);
  console.log(results);  // Results may come in a different order
};

fetchData();

This works for parallel execution, but the order of the results may not match the order of the URLs, since Promise.all() resolves them as they finish, regardless of order.

I expect the output to match the request order, even though the requests finish at different times.

Is there any way for play an audio without user interaction?

I have a Vue Js project. I use SignalR. The data flow is continuous and I follow it on ‘watch’.

watch: {
jobListAmount(newValue, oldValue) {
  if (newValue - oldValue == 1) {
    document.getElementById("clkSoundPlay").click();
  }

<button id="clkSoundPlay" @click="onClickSoundPlay" style="display: none;"></button>

I tried click a none display button with javascript but it is not work for me.
Is there any way to do this?

my javascript code working half it’s job on page load , refresh the page make it works 100% – how to fix it?

this javascript code is detecting RTL direction and set disabled Attribute to be enabled or removed on elements . wen open page the code detect the RTL direction but the disabled Attribute (add/remove) not works until refresh the page . i dont know what cause it to not work on page load !


    document.addEventListener("DOMContentLoaded", function () {
  const scrollImages = document.querySelector(".scroll-images");
  const leftButton = document.querySelector(".go_left_h");
  const rightButton = document.querySelector(".go_right_h");

  function isRTL() {
    return document.documentElement.getAttribute("dir") === "rtl";
  }

  function checkScroll() {
    const currentScroll = scrollImages.scrollLeft;
    const scrollLength = scrollImages.scrollWidth - scrollImages.clientWidth;

    if (isRTL()) {
      if (Math.abs(currentScroll) === 0) {
        rightButton.setAttribute("disabled", "true");
        leftButton.removeAttribute("disabled");
      } else if (Math.abs(currentScroll) >= scrollLength) {
        leftButton.setAttribute("disabled", "true");
        rightButton.removeAttribute("disabled");
      } else {
        leftButton.removeAttribute("disabled");
        rightButton.removeAttribute("disabled");
      }
    } else {
      if (currentScroll === 0) {
        leftButton.setAttribute("disabled", "true");
        rightButton.removeAttribute("disabled");
      } else if (currentScroll >= scrollLength) {
        rightButton.setAttribute("disabled", "true");
        leftButton.removeAttribute("disabled");
      } else {
        leftButton.removeAttribute("disabled");
        rightButton.removeAttribute("disabled");
      }
    }
  }

  scrollImages.addEventListener("scroll", checkScroll);
  window.addEventListener("resize", checkScroll);
  checkScroll();

  leftButton.addEventListener("click", leftScroll);
  rightButton.addEventListener("click", rightScroll);
});

// Move the scroll functions outside the DOMContentLoaded listener
function leftScroll() {
  const scrollImages = document.querySelector(".scroll-images");
  scrollImages.scrollBy({
    left: -200,
    behavior: "smooth"
  });
}

function rightScroll() {
  const scrollImages = document.querySelector(".scroll-images");
  scrollImages.scrollBy({
    left: 200,
    behavior: "smooth"
  });
}

can fix this issue ?

Is it possible to make a Web scraper with only on-page javascript? [closed]

Currently, I am using a Node.js backend with the Puppeteer library to simulate a browser for scraping data and then sending it back to the client.

However, my manager has requested that the entire data scraping process be moved to the client-side in order to save server resources. After doing some research on various sites and asking ChatGPT, I found that relying solely on client-side JavaScript for scraping is insufficient.

I learned that writing a browser extension could be a better option, as it offers more capabilities. However, the trade-off is that there would be no headless browsing mode, meaning the scraping process would always be visible to the user.

Any advice or guidance on how to proceed would be greatly appreciated!

Thanks in advance for help!

Extension didn’t change style of specific classes

I created a Chrome extension to highlight Google Tasks with dates in the past, today, tomorrow, and up to a week ahead.

I don’t know if this is the problem, but the extension’s code apparently runs before the tasks are loaded, which prevents the new style from being applied.

manifest.json

{
  "manifest_version": 3,
  "name": "Highlighted Google Tasks",
  "version": "1.0",
  "description": "Highlight Google Tasks with dates for today, tomorrow, and up to a week ahead.",
  "icons": {
    "16": "images/icon-16.png",
    "32": "images/icon-32.png",
    "48": "images/icon-48.png",
    "128": "images/icon-128.png"
  },
  
  "permissions": ["activeTab", "scripting"],
  
  "content_scripts": [
    {
      "matches": [
        "https://calendar.google.com/calendar/u/0/r/tasks"
      ],
      "js": ["scripts/content.js"]
    }
  ]
}

content.js

function isBeforeNextWeek(dateString) {
    const today = new Date();
    const nextWeek = new Date();
    nextWeek.setDate(today.getDate() + 7);

    const dateToCheck = new Date(dateString);

    return dateToCheck < nextWeek;
}

const ksmsgDivs = document.querySelectorAll('.KSMGS');

ksmsgDivs.forEach(ksmsg => {
    const mnEwWdDivs = ksmsg.querySelectorAll('.MnEwWd');

    var header = "";
    mnEwWdDivs.forEach(div => {
        const dataType = div.getAttribute('data-type');
        
        if (dataType === '1') {
            const divText = div.innerText.toUpperCase();
            header = divText;
        }
        else if (dataType === '0') {
            let taskColor = ""
            if (header.includes('PREVIOUS')) {
                taskColor = "#dcdcdc";
            } else if (header.includes('TODAY')) {
                taskColor = "#FFCA1A";
            } else if (header.includes('TOMORROW')) {
                taskColor = "#FFE880";
            } else {
                const possibleDate = header.match(/d{2}/d{2}/d{4}/);
                if (possibleDate && isBeforeNextWeek(possibleDate[0])) {
                    taskColor = "#FFFFCC";
                }
            }  
            
            if (taskColor) {
                div.querySelector(':first-child').style.backgroundColor = taskColor;
            }
        
        }
    });
});

Javscript Magnifying Glass Effect “failing” at edges

I’m trying to build a magnifying glass effect. This is where, when you move the cursor over an image, a magnified (ie larger) part of the image underneath the cursor is shown. I’ve gotten close with my coding. An example of what I have is this:

    let zoom = 2;

    window.addEventListener('load', () => {
      const image = document.querySelector('.image'),
        { width, height } = image.getBoundingClientRect(),
        glass = document.createElement('div');

      document.querySelector('.image-wrapper').append(glass);
      glass.classList.add('glass');
      glass.style.backgroundSize = `${zoom * width}px ${zoom * height}px`;
      glass.style.backgroundImage = `url(${image.src})`;

      image.addEventListener('mousemove', (e) => {
        const { offsetX, offsetY } = e,
          glassX = offsetX - glass.offsetWidth / 2,
          glassY = offsetY - glass.offsetHeight / 2;

        glass.style.left = `${glassX}px`;
        glass.style.top = `${glassY}px`;

        glass.style.backgroundPosition = `-${offsetX * zoom}px -${offsetY * zoom}px`;
      });
    });
   body {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background-color: #f0f0f0;
    }

    .image-wrapper {
      position: relative;
      box-sizing: border-box;
      border: 1px dashed gray;
    }

    .image {
      width: 300px;
      height: auto;
      cursor: none;
    }

    .image-wrapper .glass {
      opacity: 0;
    }

    .image-wrapper:hover .glass {
      opacity: 1;
    }

    .glass {
      position: absolute;
      width: 100px;
      height: 100px;
      border-radius: 50%;
      cursor: none;
      background-repeat: no-repeat;
      pointer-events: none;
      transition: opacity 0.2s;
      border: 1px solid black;
    }
  <div class="image-wrapper">
    <img src="https://i.sstatic.net/JzS3fR2C.jpg" alt="Sample Image" style="opacity: 0.1;" class="image">
  </div>

The source image is this
Fish

While the magnifying glass mostly works it “fails” around the edges. When the cursor gets to the edge of the image I want the glass to show a “semi circle” of the image with the other semi being white. That is I want this:
good

but I get this
bad

How to fix this so that it behaves itself around all 4 edges?

Loop through JSON response objects on postman using a Javascript function

Here below is my JSON response from an API request on postman. I wish to have a function that loops through because I am going to use the function in other requests to pick up certain objects based on the matching conditions and use their properties as variables in my next requests. In my piece of code below, I loop through the response and if an object matches the conditions, I push its index into an array. From the Array I can possibly get the objects and use its parameters in subsequent requests as variables.

API JSON response

{
    "axes": [
        {
            "id": "66ce0ert63f2982cef2e433b0aa6",
            "name": "Product 1",
            "max_number_of_days": 5,
            "tag": "Measure NPS",
            "is_validation_required": false,
            "additionnal_day_allowed": true,
            "is_pause_days_acquired_by_month": false,
            "used_days": 0,
            "booked_days": 0,
            "remaining_days": 5,
            "status": false,
            "icon": "provider_pause/stringxoNx.png",
        },
        {
            "id": "66d4e954b0f85d2ewe1b087ad408",
            "name": "Product 2",
            "max_number_of_days": 54,
            "tag": "Get App Store Ratings",
            "is_validation_required": true,
            "additionnal_day_allowed": false,
            "is_pause_days_acquired_by_month": true,
            "used_days": 0,
            "booked_days": 0,
            "remaining_days": 0,
            "status": false,
        },
        {
            "id": "67039866e21c6dfwt035a9064ed0",
            "name": "Product 3",
            "max_number_of_days": 1,
            "tag": "Garage Pause",
            "is_validation_required": false,
            "additionnal_day_allowed": true,
            "is_pause_days_acquired_by_month": true,
            "used_days": 0,
            "booked_days": 0,
            "remaining_days": 0,
            "status": false,
        },
        {
            "id": "6703f016e21c603wbf5a90ebbbe",
            "name": "Product 4",
            "max_number_of_days": 10,
            "tag": "Garage Pause",
            "is_validation_required": true,
            "additionnal_day_allowed": true,
            "is_pause_days_acquired_by_month": false,
            "used_days": 0,
            "booked_days": 0,
            "remaining_days": 10,
            "status": false,
            "icon": "product_images/c1WH.jpg",
        },
        {
            "id": "6703fed7e21sdswc6035a9103ac3",
            "name": "Product 5",
            "max_number_of_days": 5,
            "tag": "Garage Pause",
            "is_validation_required": false,
            "additionnal_day_allowed": true,
            "is_pause_days_acquired_by_month": true,
            "used_days": 0,
            "booked_days": 0,
            "remaining_days": 0,
            "status": false,
            "icon": "product_images/c1WH.jpg",
        },
        {
            "id": "6703fedae21c6035asd9103ac8",
            "name": "Product 6",
            "max_number_of_days": 5,
            "tag": "Garage Pause",
            "is_validation_required": false,
            "additionnal_day_allowed": true,
            "is_pause_days_acquired_by_month": false,
            "used_days": 0,
            "booked_days": 0,
            "remaining_days": 5,
            "status": false,
            "icon": "provider_pause/Sick Leave36cEFP.png"
        }
    ]
}
//Here is my function

    function additionalDayAllowed(jsonData){
    let permitted_objects = [];
    let number_of_pauses = jsonData.pauses.length;
    let isValidation = jsonData.pauses[i].is_validation_required;
    let isAdditional = jsonData.pauses[i].additionalDayAllowed;
    let isRemaining = jsonData.pauses[i].remaining_days;
    for (let i = 0; i < number_of_pauses; i++)
    {
        If ( isValidation === false && isAdditional === true && isRemaining > 0)
        {
           permitted_objects.push(i)
        }
        
    }
    return permitted_objects;
    }
function additionalDayAllowed(jsonData){
    let permitted_objects = [];
    let number_of_pauses = jsonData.pauses.length;
    let isValidation = jsonData.pauses[i].is_validation_required;
    let isAdditional = jsonData.pauses[i].additionalDayAllowed;
    let isRemaining = jsonData.pauses[i].remaining_days;
    for (let i = 0; i < number_of_pauses; i++)
    {
        If ( isValidation === false && isAdditional === true && isRemaining > 0)
        {
           permitted_objects.push(i)
        }
        
    }
    return permitted_objects;
   }
//Which I tried consuming in a postman sandbox as below;
 pm.test("validations", function () {
    var jsonData = pm.response.json();
    let myExtraDays = extraDaysPermitted(jsonData);
    console.log(myExtraDays[0]);

    });

Javascript stops working after highlighting search results

I put together some code for a simple search bar with a predefined list of search terms to highlight words on the page that matches the search. Everything works fine, but after clicking on a search result to highlight the words on the page, the javascript completely stops working until the page is refreshed. Here’s a snippet of the code.

function ShowSearchResults() {
    FindSearchResults();
    resultListContainer.style.display = 'block';
    setTimeout(() => {
        resultListContainer.style.transitionDuration = '300ms'
        resultListContainer.style.opacity = '1';
      }, 1);
}

function HideSearchResults() {
    resultListContainer.style.transitionDuration = '500ms'
    resultListContainer.style.opacity = '0';
    setTimeout(() => {
        resultListContainer.style.display = 'block';
      }, 500);
}

function FindSearchResults(){
    let result = [];
    let input = searchInput.value;
    if (input.length > 0){
        result = searchTerms.filter((keyword) => {
            return keyword.toLowerCase().includes(input.toLowerCase());
        });
    }
    else{
        result = searchTerms
    }
    DisplaySearchResults(result);
}

function DisplaySearchResults(result) {
    const content = result.map((list) => {
        return "<li>" + list + "</li>";
    });
    resultList.innerHTML = "<ul>" + content.join('') + "</ul>";

    document.querySelectorAll('.result-list li').forEach((item) => {
        item.addEventListener('click', function () {
            const searchText = item.textContent;
            highlightMatches(searchText);
            scrollToFirstMatch(searchText);
        });
    });
}

function highlightMatches(searchText) {
    clearHighlights(); 
    const regex = new RegExp(searchText, 'gi');

    const highlightedText = bodyText.replace(regex, (match) => {
        return `<span class="highlight-span">${match}</span>`;
    });

    document.body.innerHTML = highlightedText;

    searchInput.focus();
}

function scrollToFirstMatch(searchText) {
    const firstMatch = document.querySelector('.highlight-span');
    if (firstMatch) {
        firstMatch.scrollIntoView({
            behavior: 'smooth',
            block: 'start'
        });
    }
}

function clearHighlights() {
    document.body.innerHTML = document.body.innerHTML.replace(/<span class="highlight-span">(.*?)</span>/g, '$1');
}

Let me know if any furthur code is required!

How to compare two big number in javascript

Why below code output result is equal? How to compare?

var num1 = 340282000000000000000000000000000000001
var num2 = 340282000000000000000000000000000000000  // 3.402823E+38
if(num1 == num2) {
    console.log('num1 equal to num2');
} else if(num1 > num2) {
    console.log('num1 bigger than num2');
} else {
    console.log('num1 lower than num2')
}

How auto execute function and change stroke color to svg by percent?

I’m aproach tto js but I’ve many difficult to do the below action.

I’m using the circlifull jquery for a data counter in my web page, the data is calle ny api from the server and sent to the page by modifying the css. I have difficult to change the attribute stroke to class “circle” setting colors by percent printed in the text section.

Source code circlifull

<section id="connect-data" stroke="rgb(255, 0, 0)" class="svg-container">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 194 186" class="circliful">undefined<circle cx="100" cy="100" r="57" class="border" fill="none" stroke="#ccc" stroke-width="10" stroke-dasharray="360" transform="rotate(-90,100,100)"></circle>
<circle class="circle" cx="100" cy="100" r="57" fill="none" stroke="#008000" stroke-width="10" stroke-dasharray="36, 20000" transform="rotate(-90,100,100)"></circle>undefined<text class="timer" text-anchor="middle" x="100" y="110" style="font-size: 22px; undefined;" fill="#aaa">10%</text></svg>
</section>

I tried this test code inside to the html page for to change the color to circlifull progress bar but doesn’t work.

<script>
// Color red     --> rgb(255, 0, 0);
// Color orange  --> rgb(255, 182, 25);
// Color green   --> rgb(0, 128, 0);
$(document).ready(function() {
  if
  document.getElementById("connect-data").setAttribute ("stroke", "rgb(255, 0, 0)");
 });
</script>

How can I change the color and also setting condition for to assign:

Red under 10%
Orange 10% to 30%
Green 30%+

???

Thanks if someone can help me.

Data Counter

Section container

<section id="connect-data" stroke="rgb(255, 0, 0)" class="svg-container"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 194 186" class="circliful">undefined<circle cx="100" cy="100" r="57" class="border" fill="none" stroke="#ccc" stroke-width="10" stroke-dasharray="360" transform="rotate(-90,100,100)"></circle> <circle class="circle" cx="100" cy="100" r="57" fill="none" stroke="#008000" stroke-width="10" stroke-dasharray="36, 20000" transform="rotate(-90,100,100)"></circle>undefined<text class="timer" text-anchor="middle" x="100" y="110" style="font-size: 22px; undefined;" fill="#aaa">10%</text></svg> </section>

My JS code

<script>
// Color red     --> rgb(255, 0, 0);
// Color orange  --> rgb(255, 182, 25);
// Color green   --> rgb(0, 128, 0);
$(document).ready(function() {
  if
  document.getElementById("connect-data").setAttribute ("stroke", "rgb(255, 0, 0)");
 });
</script>

Unable to set a breakpoint in typescript VS Extension

I’ve cloned this repo…
https://github.com/semanticart/minimum-viable-vscode-language-server-extension

this is a Minimum Viable VS Code Language Server Extension with all the baseline code to develop an VS code entension.

When I try to set a breakpoint in one of the .ts or .js source code files, it does not seem to work. Once I try to debug the code with F5, another windiow will pop-up and the extesion runs fine. Initialization method get triggered but all breakpoint are greyed and VS show an error message saying “We couldn’t find a corresponding source location, and didn’t find any source with the name NameOfFile.js.

I’ve tryed look for solutions myself, firt on google and attempted meny suggestions, also tryied ask Chat GPT any everythin suggestes as the possible route cause is ok

My proyect is lacated in this folder: C:devLSPlsp-tal>

Below is the proyect struture: bind files are created and in the same .js files, main tsconfig.json and the tsconfig inside the server folder, lastly the VS configuration for run the debug session.

I someone can provide any idea or solution it will be great

Thanks is advance

these are the all posible causes according to chat gpt:

1 – Ensure Correct outFiles Paths: Your launch.json specifies paths for
the compiled files. Given that your output files are in
C:devLSPlsp-talserverout, update the outFiles pattern in your
launch.json to match:

json

“outFiles”: [ “${workspaceRoot}/server/out//*.js”,
“${workspaceRoot}/client/out/
/*.js” ]

This ensures that any subdirectories in out are included.

2 – Check Source Maps Generation: Verify that the TypeScript compiler is
generating source maps correctly. You mentioned that the output .js
files are generated in server/out. Ensure that .js.map files are
generated alongside them. If not, the debugger won’t be able to map
the TypeScript sources.

3 – Adjust sourceMap Settings in tsconfig.json: Ensure that the sourceMap
option in tsconfig.json is set to true (which it is, but just
double-check).

4 – Check File Paths in the Source Maps: Sometimes, the paths in the
generated source maps can be incorrect. Open one of the .js.map files
and verify that the sources entry points to the correct location
(e.g., ../src/parser.ts or similar). If it’s incorrect, you might need
to adjust your tsconfig.json settings like rootDir or outDir.

5 – Clean the Output Directory: Before recompiling, try deleting the out
directory to ensure no stale files are affecting the build:

bash

rm -rf server/out

6 – Verify preLaunchTask: Ensure that the npm script watch is correctly
set up in your package.json to build and watch changes. It should
ensure that files are being recompiled before starting the debugging
session.

Proyect Layout

Main - tsconfig.json

Server - tsconfig.json

VS Code launch.json

Getting Promise() when I try to send out contents with JSON file [duplicate]

I’m trying to convert a small (single page) PHP app to Javascript but having trouble accessing the contents of the JSON file.

I think it’s down to how I’ve written the JS, but as an example:

async function fetchLocalFile(filePath) {
    try {
        const response = await fetch(filePath);
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        const fileContents = await response.text();
        return fileContents;
    } catch (error) {
        console.error('Error fetching the file:', error);
    }
}

// Usage example
const filePath = 'example.json';
fetchLocalFile(filePath).then(contents => {
    console.log(contents); // this works, I get the whole json file to console
});

console.log(contents["name"][0]); // Error: contents not defined.

So my questions:

  1. How do I get contents to exist outside the fetchLocalFile request?
  2. I’d like to use this on other, similar pages. How would I move the function to another JS file (I’d like to make it as a shareable ‘utility’ function set, separate to whatever JS code I’m writing per app to save me re-writing the function).

How do I tell Google when page finishes loading with React Router?

I have a problem with Client Side Rendering for Google not working as expected.

Accordinly GSC, for the page https://zoncircle.com/item/5@xxu7o-ziaaa-aaaak-qinrq-cai the “User-declared canonical” is itself what is correct, but “Google-selected canonical” is https://zoncircle.com/item/2@xxu7o-ziaaa-aaaak-qinrq-cai what is wrong.

My guess is that Google reads https://zoncircle.com/item/5@xxu7o-ziaaa-aaaak-qinrq-cai before my code reacts to URL change and therefore before it loads (through AJAX requests) new texts, so Google uses the text from previously loaded Router page. Note that the HTML page itself normally does not reload, it just uses AJAX to display new texts when the URL changes.

How using React BrowserRouter (or in other way, if needed) can I explain Google when my page finishes loading, for it to use the finished loaded text?

I use

<Route
  path="/item/:id"
  element={<ShowItem/>}
/>

and const { id: idParam } = useParams(); in <ShowItem/>.

I use both <Link to=...> and navigate(...) for user navigating my site.

Accordngly to Google, its search engine can use client-side rendering, but it doesn’t work in my case.

I guess, I should call navigate() after the navigated-to page fully loads (How to do this elegenatly, that is in an object-oriented manner?) This is not easy to do in an object-oriented manner. With <Link to=...> tag, it is even harder (if not impossible) to do, because it (as far as I know) calls navigate() immediately after moving to the new URL, without any waiting (e.g. of when AJAX loads). So, should I eliminate using <Link to=...> as a feature incompatible with SEO? In short: How to do it with React Router?