How do I write this code without using .innerHTML?

I am writing a JavaScript code where some characters of the string have a color and I want to display them through the HTML elements. I only want the ‘abc’ to be blue and no color change with ‘def’.

For example, if there’s a variable:

word = '<span style="color: blue">abc</span>def'

I used this to display the text in the HTML element:

presentCell.innerHTML = word;

Is there a way to not use .innerHTML and do the same thing? I’m worried about security problems because I am getting user input for ‘abc’ and ‘def’.

I am making this word variable with this function:

function changeTextColorArr (textArr, colorArr){
    resultArr = [];
    for(let i = 0; i < textArr.length; i++)
    {
        color = colorArr[i] === "" ? "black" : colorArr[i];
        beginTag =   `<span style="color: ${color}">`
        endTag= '</span>';

        result = beginTag + textArr[i] + endTag;
        resultArr.push(result);
    }
    return resultArr;
}
//I get an array of an text and an array of colors correspoding to each text

let word = changeTextColorArr(["abc"], ["blue"]) + "def"; 
console.log(word)

Issue fetching token balance from connected wallet using Solana, Jupiter Aggregator, and Jupiter APIs

I’m having trouble fetching the balance of a specific token from the connected wallet when swapping tokens using Solana, Jupiter Aggregator, and Jupiter APIs. I’ve implemented a server-side API to handle the swap process, which includes fetching quotes, generating swap instructions, and transferring platform fees using Jupiter APIs. However, I’m encountering an issue where the balance from the connected wallet is not being fetched correctly.

I’m using the getTokenAccountBalance and getAssociatedTokenAddress methods from the @solana/web3.js library to fetch the balance. Here’s the relevant code snippet from my server.js file:

app.get("/fetchBalance", async (req, res) => {
  const { address, walletAddress } = req.query;
  try {
    const tokenPublicKey = new PublicKey(address);
    const walletPublicKey = new PublicKey(walletAddress);

    const balance = await connection.getTokenAccountBalance(
      await connection.getAssociatedTokenAddress(tokenPublicKey, walletPublicKey)
    );

    return res.status(200).json({
      balance: balance.value.uiAmount,
      decimals: balance.value.decimals
    });
  } catch (error) {
    console.error("Error fetching token balance:", error);
    return res.status(500).json({ error: "Error fetching token balance" });
  }
});

And here’s the relevant code snippet from my swap.js file:

const fetchTokenBalance = useCallback(async (tokenAddress) => {
  if (!publicKey) return;

  try {
    const response = await axios.get("http://localhost:3001/fetchBalance", {
      params: {
        address: tokenAddress,
        walletAddress: publicKey.toString(),
      },
    });
    const balance = response.data.balance;
    setBalances(prevBalances => ({ ...prevBalances, [tokenAddress]: balance }));
    updateTokenBalances({ ...balances, [tokenAddress]: balance });
  } catch (error) {
    console.error("Error fetching token balance:", error);
    messageApi.error("Failed to fetch token balance");
  }
}, [publicKey, updateTokenBalances, balances, messageApi]);

I’m also using Jupiter APIs to fetch prices for the tokens being swapped. Here’s the relevant code snippet from my server.js file:

app.get("/tokenPrice", async (req, res) => {
  const { addressOne, addressTwo } = req.query;
  try {
    const response = await axios.get(`https://price.jup.ag/v6/price`, {
      params: { ids: addressOne, vsToken: addressTwo },
    });
    const priceData = response.data.data[addressOne];
    if (!priceData || !priceData.price) {
      throw new Error("Invalid response from price API");
    }
    const usdPrices = {
      tokenOne: priceData.price,
      tokenTwo: 1 / priceData.price,
      ratio: priceData.price,
    };
    return res.status(200).json(usdPrices);
  } catch (error) {
    console.error("Error fetching token prices:", error);
    return res.status(500).json({ error: "Error fetching token prices" });
  }
});

I’ve added some logging statements to the fetchTokenBalance function to see if it’s being called correctly and if the correct token address and wallet address are being passed to the getTokenAccountBalance and getAssociatedTokenAddress methods. However, I’m still not able to determine the root cause of the issue.

Can anyone help me understand what might be causing the issue with fetching the balance from the connected wallet, and how I can fix it? Additionally, is fetching the balance important for swapping tokens, and if so, how does it fit into the overall swap process?

i have tried everything hlep plz

How can I grab the source of a Javascript dynamically generated image so I can create a download button on mobile browser?

I am using a script qrcode.js to generate a QR-code that I want to download so it can be ‘scanned’ on a mobile phone. The QR-code image is created after the user fills in a form and the data is used to generate the image.

I can get the download button to work on the desktop and on a mobile if the browser runs in ‘Desktop mode’. That mean that on a mobile I have to use: ‘Request Desktop Site’, that is available in Chrome on Android mobile. In regular mode in Chome on Android mobile, however, using tap and hold on the download button downloads the entire HTML file.

To figure out what was going on, I tried to alert() the source of the image after using querySelector to grab it. On the desktop browser and in ‘Desktop mode’ for in Chome on Android mobile, I am able to get the file source printed in the alert box, but in regular mode on the mobile browser, it returns an empty string. Also, although the image still appears on the mobile page, I cannot tap and hold on to it in order to initiate a download. If I use another image, as in the code below, that is not generated by Javascript, I can download it with no issue.

<img src="logo.png" alt="" class="mb-10"/>

This is how the QR-image is generated and how the download button is created:

const form = document.getElementById('generate-form');
const qr = document.getElementById('qrcode');

const onGenerateSubmit = (e) => {
    e.preventDefault();

    clearUI();

    const name = document.getElementById('name').value;
    var radios = document.getElementsByName("svc");
    let reference = service + ' ' + name;
    
    setTimeout(() => {
        // Generate the QR code with qrcode.js
        generateQRCode(reference);

        setTimeout(() => {
            // Grab the src of the QR image
            const saveUrl = qr.querySelector("img").src;
            createSaveBtn(saveUrl);
        }, 1000);
    }, 50);

}

const generateQRCode = (url) => {
    const qrcode = new QRCode('qrcode', {
        text: url,
        width: 300,
        height: 300,
    });
}

const createSaveBtn = (saveUrl) => {
    const link = document.createElement('a');
    link.id = 'save-link';
    alert(saveUrl);
    link.classList = 'bg-red-500 hover:bg-red-700  text-white font-bold py-2 rounded w-1/3 m-auto my-5';
    link.href = saveUrl;
    link.download = 'qrcode';
    link.innerHTML = 'Save Image';
    document.getElementById('generated').appendChild(link);
};

const clearUI = () => {
    qr.innerHTML = '';
    const saveBtn = document.getElementById('save-link');
    if (saveBtn) saveBtn.remove();
}

form.addEventListener('submit', onGenerateSubmit);

Below are the images of the alert box that shows the src of the QR code in the different modes on mobile:

On mobile

On mobile while in Request Desktop Site

Is there a way I can get the src of the dynamically generated image on mobile? Does a browser work differently on a mobile than on a desktop? I have noticed that on other websites, there are certain images that I can’t download with tap and hold as well.

I’m new to Javascript and HTML so any help is very much appreciated. Thank you so much in advanced.

How to Add an Onclick event with React.forwardRef to open a Modal Box

I am an electrical engineer attempting to write a portfolio with JavaScript and Typescript, apologies if my question is trivial.

The following code, created a generalised parent, which creates ‘cards’ of work experience.

The following code works correctly, but I am trying to add an onclick event to the child events. I attempt to add an ‘onclick’ attribute to open a simple modal box with some text, but I am getting errors stating I need :

React.MouseEventHandler<HTMLAnchorElement>

I am wondering if there is a way to add an ‘onclick event’ to these child events? Specifically the “works-card” class? Or how to redeclare this block with a MouseEveentHandler?

I would really appreciate any help!

import React from 'react'
import { Github, Link, works } from '../../../library'
import { Headings } from '../../core/headings/headings'
import './style.css'

const Works = React.forwardRef<HTMLDivElement>((props, ref) => {
  return (
    <div ref={ref} className="works">
      {/*  Display the section title and subtitle */}
      <Headings title="Working" subtitle="Places I've Worked" />
      <div className="projects-grid">
        {works.map((work) => (
          <a
            className="works-card"
            target="_blank"
            key={work.title}
            rel="noreferrer"
            
          >
            <p className="project-name">{work.title}</p>
            <div className="project-language">
              {work.languages.map((language) => (
                <span key={language}>{language}</span>
              ))}
            </div>
          </a>
        ))}
      </div>
    </div>
  )
})



Works.displayName = 'Works'

export { Works }





Thankyou!

I have tried to ad an “onClick” attribute, with errors.

Why is redirect not working in Production build. NextJS14

I’m triying to authenticate through the production build of my project. However, I found out that there’s an issue with redirect().

I initially though it was a server error on my ExpressJS backend but I checked the logs and the POST request is succesful, however, the front end is not setting up cookies as it should and thus redirect fails.

import {
  fetchurl,
  setAuthTokenOnServer,
  setUserOnServer,
} from '@/helpers/setTokenOnServer'
import { redirect } from 'next/navigation'
import FormButtons from '@/components/global/formbuttons'

const Login = async ({ params, searchParams }) => {

  const loginAccount = async (formData) => {
    'use server'
    const rawFormData = {
      email: formData.get('email'),
      password: formData.get('password')
    }

    const res = await fetchurl(`/auth/login`, 'POST', 'no-cache', rawFormData);

    if (res?.data) {
      redirect(`/auth/validatetwofactorauth/${res?.data?._id}`)
    }

    // If not success, stop
    if (!res?.success) return;
    
    await setAuthTokenOnServer(res?.token); // Sets auth cookies on server
    const loadUser = await fetchurl(`/auth/me`, 'GET', 'no-cache'); // loads user based on auth
    await setUserOnServer(loadUser?.data); // then sets some user's values into cookies
    searchParams?.returnpage ? redirect(searchParams.returnpage) : redirect(`/auth/profile`);
  }

  return (
    <form action={loginAccount}>
      <label htmlFor="email" className="form-label">
        Email
      </label>
      <input
        id="email"
        name="email"
        type="email"
        className="form-control mb-3"
        placeholder="[email protected]"
      />
      <label htmlFor="password" className="form-label">
        Password
      </label>
      <input
        id="password"
        name="password"
        type="password"
        className="form-control mb-3"
        placeholder="******"
      />
      <br />
      <FormButtons />
    </form>
  )
}

export default Login

Anyone has dealt with this before? I’d like to keep the page in the server side as much as possible.

Click here to see local vs production build examples

Thanks in advance!.

RegExp for checking whole decimal numbers mixed with special chars

I need a RegExp to test strings that should consist of the valid whole decimal numbers including zero (0, 1, 12, 123, but not 00 or 0123) mixed with a special character (such as x) in free occurrences:

0, 1, 123, x, xx, x0, 0x, x0x, 0x0, xx123x0, x1000xx5xxx, …

I came up with the following:

new RegExp('^0?$|^((?!0)[0-9]+|x0$|0x|x+)+$')

Unfortunately, it do not work 100%, e.g. a valid string is not accepted: 0x0.

Thanks for any help!

Vite build not including css file with ?inline tag

I have this project (Project A), which has npm installed another package of mine (Project B). this package (Project B) has multiple inline CSS files which it imports as “import abc from “../../file.css?inline”

This works for this package(Project B) as standalone, and when I build my vite project(Project A) which has it (Project B) installed in it’s node_modules while it’s symlinked (npm link) it also imports it as a string in the resulting .js file it builds. However, when I install Project B as a regular NPM package, it doesn’t import the ?inline file into the resulting .js file.

Project B has the following code in it’s rollup config to make it work for it standalone:

function cssInline() {
  return {
    name: 'css-inline',
    resolveId(source) {
      if (source.endsWith('?inline')) {
        console.log('css-inline plugin resolveId:', source);
        return source;
      }
      return null;
    },
    load(id) {
      if (id.endsWith('?inline')) {
        const filePath = id.replace('?inline', '');
        const absolutePath = path.isAbsolute(filePath)
          ? filePath
          : path.resolve(process.cwd(), filePath);

        console.log('css-inline plugin load:', absolutePath);

        try {
          const css = fs.readFileSync(absolutePath, 'utf-8');
          console.log('css-inline plugin css content length:', css.length);
          return `export default ${JSON.stringify(css)}`;
        } catch (err) {
          console.error(`Error reading CSS file ${absolutePath}:`, err);
          return `export default 'test'`;
        }
      }
      return null;
    },
  };
}

Give Image quality

While capturing image i am getting poor quality of image
My capture image code is

  private async Task CaptureImage()
  {
      Snackbar.Clear();
      Snackbar.Configuration.PositionClass = Defaults.Classes.Position.TopCenter;

      if (SavedImages.Count + selectedImagesFromSM.Count < 3)
      {
          var options = new DialogOptions
              {
                  FullWidth = true,
                  DisableBackdropClick = true,
                  Position = DialogPosition.Center
              };

          var result = await DialogService.Show<ImageCaptureDialog>("Capture Image", options).Result;

          if (!result.Cancelled)
          {
              string imageUri = result.Data.ToString();
              byte[] bytes = Convert.FromBase64String(imageUri.Split(',')[1]);

              if (bytes.Length > Constants.IMAGE_MAX_SIZE)
              {
                  Snackbar.Add($"The Captured image exceeds the maximum size limit : 20 MB.", Severity.Warning);
              }
              else
              {
                  byte[] imageStreamToBytes;

                  using (var image = SixLabors.ImageSharp.Image.Load(bytes))
                  {
                      using (MemoryStream outputStream = new MemoryStream())
                      {
                          var encoder = new SixLabors.ImageSharp.Formats.Jpeg.JpegEncoder { Quality = 100 };
                          image.Save(outputStream, encoder);

                          imageStreamToBytes = outputStream.ToArray();
                      }
                  }

                  selectedImagesFromSM.Add(new ITSImage { PartNumber = int.Parse(selectedPartNumber), Images = new List<Image> { new Image { Data = imageStreamToBytes } } });
              }

              await CheckPartNumberImageCount();
          }
      }
      else
      {
          Snackbar.Add("You can capture only 3 images.", Severity.Warning);
      }
  }

camera.js function is

async function startVideo(src) {
    try {
        const permission = await checkCameraPermission();
        if (permission === 'prompt' || permission === 'granted') {
            navigator.getUserMedia(
                { video: true, audio: false },
                function (localMediaStream) {
                    let video = document.getElementById(src);
                    video.srcObject = localMediaStream;
                    video.onloadedmetadata = function (e) {
                        video.play();
                    };
                },
                function (err) {
                    console.error('Error accessing camera:', err);
                    throw err; // Propagate the error
                }
            );
        } else {
            console.error('Camera permission denied.');
        }
    } catch (error) {
        console.error('Error starting video:', error);
    }
}

function getFrame(src, dest, dotnetHelper) {
    let video = document.getElementById(src);
    let canvas = document.getElementById(dest);

    // Check if the video and canvas elements exist before drawing the image
    if (video && canvas) {
        canvas.getContext('2d').drawImage(video, 0, 0, 150, 150);

        // Resize the image on the canvas
        let resizedCanvas = document.createElement('canvas');
        resizedCanvas.width = 200; // Set desired width
        resizedCanvas.height = 200; // Set desired height
        let ctx = resizedCanvas.getContext('2d');
        ctx.drawImage(canvas, 0, 0, resizedCanvas.width, resizedCanvas.height);

        // Convert the resized image to base64 JPEG format
        let dataUrl = resizedCanvas.toDataURL("image/jpeg");

        // Invoke the .NET method with the resized image data
        dotnetHelper.invokeMethodAsync('ProcessImage', dataUrl);
    } else {
        console.error('Video or canvas element not found.');
    }
}

I have Added the code please check where i am doing mistake

Although my camera produces good quality images, the captured images in my application appear low-quality. How can I improve the image quality?

When does popstate fires?

There is exactly a same question in StackOverflow, but I found that the browser keeps updating when to fire it(different browser performs differently), also I saw someone’s comment on an answer citing MDN docs, where he says that “I don’t think this is still true”.

As per my understanding as we continue clicking links, pushstate fires for every new page load with the content and URL mapped for every page. When we press back/forward button the browser doesn’t send a request to the URL we are returning to, rather it fires a popstate event, the event has a state variable which is earlier content loaded when we first visited the URL. And hence the browser without any reloading shows the content of that particular URL. Is this the correct way to think about?

Now this site explains the popstate by stating that it fires when we navigate into the same document object as the same page or we traverse the URL already present in history stack.

To support navigation into the same document object it cites an example of going to a link having a href (# ammended) for example going from www.example.com/home to www.example.com/home#glossarys fires a popstate (mentioned in Task 2 of the site). This is true because the entire document object gets loaded (for example a long webpage) so going to specified part of the document should not trigger a document load. But I am unable to understand how popstate gets the data what it should fetch when we visit a part of the webpage. Because for that particular link containing a # pushstate has not been triggered.

Also in Task 4 of the website, it mentioned that going back from www.example.com/home#glossarys to www.example.com/home will not fire a pop state as the document object will reload. But the document object is already loaded why its going to load again.

reloading my page once trigger my api request multiple times

so basically I’m learning web development on my Lenovo Legion 5 pro-Windows laptop and I’m working with javascript APIs whenever from my chrome I send a single get request by refreshing a page in that path it gets 3 to 4 requests automatically and if I was saving data in get request in mongodb then it saving multiple 3 to 4 same data at with a single refresh please help me how to get rid of this problem or you can a glitch?

please tell me some solution to get rid of this problem

Mapbox wont change map colors

Hi I’m trying to change some colors but mapbox wont do this.

I’ve searched across the internet and it seems that my code is right but changes wont take effect.
`

    map.addLayer({
        'id': 'entidades',
        'source': 'estados',
        'source-layer': 'tasasyconteos_ent_updated-86v9k0',
        'maxzoom': zoomThreshold,
        'type': 'fill',
        'paint': {
            'fill-color': ['interpolate', ['linear'],
                ['get', 'POBTOT'],
                0, '#f0f9e8',
                5000000, '#bae4bc',
                10000000, '#7bccc4',
                15000000, '#ff0000',
                25000000, '#0868ac'
            ],
            'fill-opacity': 1,
            'fill-outline-color': 'black'
        }
    }, 'road-label-simple');

Data scraping from a web page – where are the data from a chart held?

I am trying to scrap the stock data from the chart of the following link : https://www.boursorama.com/cours/1rPADP/

Searching “chartData” in the dev console provides me something that looks like it :

                                            $(function() {
                                            //The amCharts "real" default configs for our charts can be found in the jQuery plugin "jquery.amcharts.js".
                                            var chart = JSON.parse('{"static":{"amChart":{"type":"serial"},"graph":{"fillAlphas":0,"fillColors":"#009de0","lineColor":"#009de0","gridColor":"#000000","fontColor":"#000000","categoryOffset":0,"chartModifier":"c-chart--height-xs"}},"data":{"amChartConfig":{"brs":{"commonField":"period","id":2068349295},"colors":["#009de0","#003883","#149e62","#f1d205"],"valueAxes":[{"title":"","position":"right","axisThickness":0,"gridThickness":1,"gridColor":"#000000","tickLength":0,"guides":[{"value":111.7,"lineColor":"#fb0189","lineAlpha":100,"lineThickness":1,"tickLength":0,"above":true}],"includeGuidesInMinMax":true,"color":"#000000"}],"categoryAxis":{"axisThickness":0,"gridThickness":0,"autoGridCount":false,"gridCount":3,"showFirstLabel":false,"showLastLabel":false,"color":"#000000","offset":0},"graphs":[{"balloonText":"[[title]] [[category]] : [[value]]","type":"line","fillAlphas":0,"fillColors":"#009de0","id":"chart-66b4681376323","commonField":"period","brsValueField":"value","lineThickness":1}],"chartCursor":{"valueBalloonsEnabled":true,"valueLineEnabled":true,"cursorAlpha":0.35,"cursorColor":"#009de0","valueLineBalloonEnabled":true,"categoryBalloonColor":"#009de0","valueLineAlpha":0.35,"valueZoomable":false,"pan":false,"zoomable":false}},"amChartData":{"chart-66b4681376323":[{"period":"09h00","value":112.9},{"period":"09h01","value":112.7},{"period":"09h02","value":112.5},{"period":"09h03","value":112.6},{"period":"09h04","value":112.7},{"period":"09h05","value":112.7},{"period":"09h06","value":112.7},{"period":"09h07","value":112.9},{"period":"09h08","value":112.8},{"period":"09h09","value":112.4},{"period":"09h10","value":112.6},{"period":"09h11","value":112.5},{"period":"09h12","value":112.5},{"period":"09h13","value":112.2},{"period":"09h14","value":112.2},{"period":"09h15","value":112.5},{"period":"09h16","value":112.5},{"period":"09h17","value":112.7},{"period":"09h18","value":112.8},{"period":"09h19","value":112.8},{"period":"09h20","value":112.6},{"period":"09h21","value":112.8},{"period":"09h22","value":112.7},{"period":"09h23","value":112.7},{"period":"09h24","value":112.4},{"period":"09h25","value":112.4},{"period":"09h26","value":112.5},{"period":"09h27","value":112.5},{"period":"09h28","value":112.6},{"period":"09h29","value":112.6},{"period":"09h30","value":112.6},{"period":"09h31","value":112.8},{"period":"09h32","value":112.7},{"period":"09h33","value":112.8},{"period":"09h34","value":112.8},{"period":"09h35","value":112.9},{"period":"09h36","value":113.1},{"period":"09h37","value":113.3},{"period":"09h38","value":113.3},{"period":"09h39","value":113.2},{"period":"09h40","value":113.2},{"period":"09h41","value":113.1},{"period":"09h42","value":113.2},{"period":"09h43","value":113.1},{"period":"09h44","value":113},{"period":"09h45","value":113},{"period":"09h46","value":113.1},{"period":"09h47","value":113.2},{"period":"09h48","value":113.2},{"period":"09h49","value":113.2},{"period":"09h50","value":113.3},{"period":"09h51","value":113.3},{"period":"09h52","value":113.4},{"period":"09h53","value":113.3},{"period":"09h54","value":113.2},{"period":"09h55","value":113.2},{"period":"09h56","value":113.2},{"period":"09h57","value":113.2},{"period":"09h58","value":113.2},{"period":"09h59","value":113.2},{"period":"10h00","value":112.9},{"period":"10h01","value":113},{"period":"10h02","value":113},{"period":"10h03","value":113},{"period":"10h04","value":113},{"period":"10h05","value":113},{"period":"10h06","value":113.2},{"period":"10h07","value":113.2},{"period":"10h08","value":113.2},{"period":"10h09","value":113.2},{"period":"10h10","value":113.2},{"period":"10h11","value":113.2},{"period":"10h12","value":113.2},{"period":"10h13","value":113.2},{"period":"10h14","value":113.2},{"period":"10h15","value":113.2},{"period":"10h16","value":113.2},{"period":"10h17","value":113.3},{"period":"10h18","value":113.1},{"period":"10h19","value":113},{"period":"10h20","value":113},{"period":"10h21","value":113},{"period":"10h22","value":113},{"period":"10h23","value":112.8},{"period":"10h24","value":113},{"period":"10h25","value":113},{"period":"10h26","value":113},{"period":"10h27","value":112.9},{"period":"10h28","value":112.8},{"period":"10h29","value":112.8},{"period":"10h30","value":112.8},{"period":"10h31","value":112.8},{"period":"10h32","value":112.8},{"period":"10h33","value":112.8},{"period":"10h34","value":112.8},{"period":"10h35","value":112.9},{"period":"10h36","value":112.9},{"period":"10h37","value":112.9},{"period":"10h38","value":112.9},{"period":"10h39","value":112.9},{"period":"10h40","value":112.9},{"period":"10h41","value":112.9},{"period":"10h42","value":112.9},{"period":"10h43","value":112.9},{"period":"10h44","value":112.9},{"period":"10h45","value":112.9},{"period":"10h46","value":112.9},{"period":"10h47","value":113},{"period":"10h48","value":113},{"period":"10h49","value":113.1},{"period":"10h50","value":113},{"period":"10h51","value":113},{"period":"10h52","value":113},{"period":"10h53","value":113},{"period":"10h54","value":113},{"period":"10h55","value":113},{"period":"10h56","value":113},{"period":"10h57","value":113},{"period":"10h58","value":113},{"period":"10h59","value":113.2},{"period":"11h00","value":113},{"period":"11h01","value":113},{"period":"11h02","value":113},{"period":"11h03","value":113.1},{"period":"11h04","value":113},{"period":"11h05","value":113},{"period":"11h06","value":113},{"period":"11h07","value":113.1},{"period":"11h08","value":113.1},{"period":"11h09","value":113.1},{"period":"11h10","value":112.8},{"period":"11h11","value":112.9},{"period":"11h12","value":112.9},{"period":"11h13","value":113},{"period":"11h14","value":113},{"period":"11h15","value":113},{"period":"11h16","value":112.8},{"period":"11h17","value":112.9},{"period":"11h18","value":112.9},{"period":"11h19","value":112.9},{"period":"11h20","value":112.9},{"period":"11h21","value":112.9},{"period":"11h22","value":112.9},{"period":"11h23","value":113},{"period":"11h24","value":113},{"period":"11h25","value":113},{"period":"11h26","value":112.9},{"period":"11h27","value":112.9},{"period":"11h28","value":112.9},{"period":"11h29","value":112.9},{"period":"11h30","value":113},{"period":"11h31","value":113},{"period":"11h32","value":113},{"period":"11h33","value":113},{"period":"11h34","value":113},{"period":"11h35","value":113},{"period":"11h36","value":113},{"period":"11h37","value":113.1},{"period":"11h38","value":113.1},{"period":"11h39","value":113.1},{"period":"11h40","value":113.1},{"period":"11h41","value":113.1},{"period":"11h42","value":113.1},{"period":"11h43","value":112.9},{"period":"11h44","value":112.8},{"period":"11h45","value":112.8},{"period":"11h46","value":112.7},{"period":"11h47","value":112.8},{"period":"11h48","value":112.8},{"period":"11h49","value":112.7},{"period":"11h50","value":112.7},{"period":"11h51","value":112.8},{"period":"11h52","value":113},{"period":"11h53","value":113},{"period":"11h54","value":113},{"period":"11h55","value":113},{"period":"11h56","value":113},{"period":"11h57","value":113},{"period":"11h58","value":113},{"period":"11h59","value":113},{"period":"12h00","value":113.2},{"period":"12h01","value":113.2},{"period":"12h02","value":113.2},{"period":"12h03","value":113.2},{"period":"12h04","value":113.2},{"period":"12h05","value":113.2},{"period":"12h06","value":113.2},{"period":"12h07","value":113.2},{"period":"12h08","value":113.2},{"period":"12h09","value":113.3},{"period":"12h10","value":113.3},{"period":"12h11","value":113.3},{"period":"12h12","value":113.3},{"period":"12h13","value":113.4},{"period":"12h14","value":113.4},{"period":"12h15","value":113.4},{"period":"12h16","value":113.4},{"period":"12h17","value":113.4},{"period":"12h18","value":113.4},{"period":"12h19","value":113.4},{"period":"12h20","value":113.2},{"period":"12h21","value":113.2},{"period":"12h22","value":113.2},{"period":"12h23","value":113.2},{"period":"12h24","value":112.9},{"period":"12h25","value":112.9},{"period":"12h26","value":112.8},{"period":"12h27","value":112.8},{"period":"12h28","value":112.8},{"period":"12h29","value":112.6},{"period":"12h30","value":112.7},{"period":"12h31","value":112.7},{"period":"12h32","value":112.7},{"period":"12h33","value":112.5},{"period":"12h34","value":112.5},{"period":"12h35","value":112.5},{"period":"12h36","value":112.5},{"period":"12h37","value":112.5},{"period":"12h38","value":112.5},{"period":"12h39","value":112.5},{"period":"12h40","value":112.5},{"period":"12h41","value":112.4},{"period":"12h42","value":112.3},{"period":"12h43","value":112.3},{"period":"12h44","value":112.3},{"period":"12h45","value":112.4},{"period":"12h46","value":112.3},{"period":"12h47","value":112.3},{"period":"12h48","value":112.3},{"period":"12h49","value":112.3},{"period":"12h50","value":112.4},{"period":"12h51","value":112.4},{"period":"12h52","value":112.4},{"period":"12h53","value":112.4},{"period":"12h54","value":112.4},{"period":"12h55","value":112.4},{"period":"12h56","value":112.6},{"period":"12h57","value":112.5},{"period":"12h58","value":112.5},{"period":"12h59","value":112.5},{"period":"13h00","value":112.5},{"period":"13h01","value":112.5},{"period":"13h02","value":112.5},{"period":"13h03","value":112.5},{"period":"13h04","value":112.7},{"period":"13h05","value":112.7},{"period":"13h06","value":112.7},{"period":"13h07","value":112.7},{"period":"13h08","value":112.6},{"period":"13h09","value":112.7},{"period":"13h10","value":112.7},{"period":"13h11","value":112.7},{"period":"13h12","value":112.7},{"period":"13h13","value":112.7},{"period":"13h14","value":112.7},{"period":"13h15","value":112.7},{"period":"13h16","value":112.7},{"period":"13h17","value":112.7},{"period":"13h18","value":112.7},{"period":"13h19","value":112.7},{"period":"13h20","value":112.5},{"period":"13h21","value":112.5},{"period":"13h22","value":112.5},{"period":"13h23","value":112.5},{"period":"13h24","value":112.5},{"period":"13h25","value":112.5},{"period":"13h26","value":112.6},{"period":"13h27","value":112.6},{"period":"13h28","value":112.6},{"period":"13h29","value":112.6},{"period":"13h30","value":112.6},{"period":"13h31","value":112.6},{"period":"13h32","value":112.6},{"period":"13h33","value":112.6},{"period":"13h34","value":112.6},{"period":"13h35","value":112.6},{"period":"13h36","value":112.5},{"period":"13h37","value":112.4},{"period":"13h38","value":112.4},{"period":"13h39","value":112.4},{"period":"13h40","value":112.4},{"period":"13h41","value":112.4},{"period":"13h42","value":112.4},{"period":"13h43","value":112.4},{"period":"13h44","value":112.6},{"period":"13h45","value":112.6},{"period":"13h46","value":112.6},{"period":"13h47","value":112.5},{"period":"13h48","value":112.5},{"period":"13h49","value":112.5},{"period":"13h50","value":112.5},{"period":"13h51","value":112.5},{"period":"13h52","value":112.5},{"period":"13h53","value":112.5},{"period":"13h54","value":112.5},{"period":"13h55","value":112.5},{"period":"13h56","value":112.4},{"period":"13h57","value":112.3},{"period":"13h58","value":112.3},{"period":"13h59","value":112.3},{"period":"14h00","value":112.3},{"period":"14h01","value":112.3},{"period":"14h02","value":112.3},{"period":"14h03","value":112.3},{"period":"14h04","value":112.3},{"period":"14h05","value":112.3},{"period":"14h06","value":112.3},{"period":"14h07","value":112.4},{"period":"14h08","value":112.4},{"period":"14h09","value":112.4},{"period":"14h10","value":112.4},{"period":"14h11","value":112.3},{"period":"14h12","value":112.3},{"period":"14h13","value":112.3},{"period":"14h14","value":112.5},{"period":"14h15","value":112.5},{"period":"14h16","value":112.5},{"period":"14h17","value":112.5},{"period":"14h18","value":112.5},{"period":"14h19","value":112.5},{"period":"14h20","value":112.5},{"period":"14h21","value":112.5},{"period":"14h22","value":112.5},{"period":"14h23","value":112.5},{"period":"14h24","value":112.5},{"period":"14h25","value":112.5},{"period":"14h26","value":112.5},{"period":"14h27","value":112.5},{"period":"14h28","value":112.5},{"period":"14h29","value":112.5},{"period":"14h30","value":112.5},{"period":"14h31","value":112.5},{"period":"14h32","value":112.6},{"period":"14h33","value":112.6},{"period":"14h34","value":112.6},{"period":"14h35","value":112.6},{"period":"14h36","value":112.5},{"period":"14h37","value":112.5},{"period":"14h38","value":112.5},{"period":"14h39","value":112.5},{"period":"14h40","value":112.5},{"period":"14h41","value":112.5},{"period":"14h42","value":112.5},{"period":"14h43","value":112.5},{"period":"14h44","value":112.5},{"period":"14h45","value":112.5},{"period":"14h46","value":112.5},{"period":"14h47","value":112.5},{"period":"14h48","value":112.6},{"period":"14h49","value":112.6},{"period":"14h50","value":112.6},{"period":"14h51","value":112.7},{"period":"14h52","value":112.7},{"period":"14h53","value":112.7},{"period":"14h54","value":112.7},{"period":"14h55","value":112.6},{"period":"14h56","value":112.6},{"period":"14h57","value":112.6},{"period":"14h58","value":112.6},{"period":"14h59","value":112.6},{"period":"15h00","value":112.6},{"period":"15h01","value":112.6},{"period":"15h02","value":112.6},{"period":"15h03","value":112.6},{"period":"15h04","value":112.6},{"period":"15h05","value":112.6},{"period":"15h06","value":112.5},{"period":"15h07","value":112.5},{"period":"15h08","value":112.6},{"period":"15h09","value":112.6},{"period":"15h10","value":112.6},{"period":"15h11","value":112.6},{"period":"15h12","value":112.6},{"period":"15h13","value":112.5},{"period":"15h14","value":112.5},{"period":"15h15","value":112.5},{"period":"15h16","value":112.5},{"period":"15h17","value":112.6},{"period":"15h18","value":112.6},{"period":"15h19","value":112.6},{"period":"15h20","value":112.6},{"period":"15h21","value":112.6},{"period":"15h22","value":112.6},{"period":"15h23","value":112.6},{"period":"15h24","value":112.6},{"period":"15h25","value":112.6},{"period":"15h26","value":112.6},{"period":"15h27","value":112.6},{"period":"15h28","value":112.6},{"period":"15h29","value":112.6},{"period":"15h30","value":112.5},{"period":"15h31","value":112.5},{"period":"15h32","value":112.4},{"period":"15h33","value":112.4},{"period":"15h34","value":112.3},{"period":"15h35","value":112.4},{"period":"15h36","value":112.2},{"period":"15h37","value":112.2},{"period":"15h38","value":112.2},{"period":"15h39","value":112.4},{"period":"15h40","value":112.4},{"period":"15h41","value":112.4},{"period":"15h42","value":112.4},{"period":"15h43","value":112.4},{"period":"15h44","value":112.4},{"period":"15h45","value":112.4},{"period":"15h46","value":112.4},{"period":"15h47","value":112.4},{"period":"15h48","value":112.4},{"period":"15h49","value":112.4},{"period":"15h50","value":112.4},{"period":"15h51","value":112.4},{"period":"15h52","value":112.4},{"period":"15h53","value":112.4},{"period":"15h54","value":112.5},{"period":"15h55","value":112.3},{"period":"15h56","value":112.5},{"period":"15h57","value":112.5},{"period":"15h58","value":112.5},{"period":"15h59","value":112.4},{"period":"16h00","value":112.5},{"period":"16h01","value":112.5},{"period":"16h02","value":112.5},{"period":"16h03","value":112.5},{"period":"16h04","value":112.5},{"period":"16h05","value":112.5},{"period":"16h06","value":112.5},{"period":"16h07","value":112.6},{"period":"16h08","value":112.6},{"period":"16h09","value":112.6},{"period":"16h10","value":112.6},{"period":"16h11","value":112.6},{"period":"16h12","value":112.6},{"period":"16h13","value":112.5},{"period":"16h14","value":112.5},{"period":"16h15","value":112.5},{"period":"16h16","value":112.5},{"period":"16h17","value":112.5},{"period":"16h18","value":112.5},{"period":"16h19","value":112.6},{"period":"16h20","value":112.6},{"period":"16h21","value":112.6},{"period":"16h22","value":112.6},{"period":"16h23","value":112.5},{"period":"16h24","value":112.5},{"period":"16h25","value":112.5},{"period":"16h26","value":112.4},{"period":"16h27","value":112.5},{"period":"16h28","value":112.4},{"period":"16h29","value":112.4},{"period":"16h30","value":112.4},{"period":"16h31","value":112.3},{"period":"16h32","value":112.1},{"period":"16h33","value":112.1},{"period":"16h34","value":112},{"period":"16h35","value":111.9},{"period":"16h36","value":111.8},{"period":"16h37","value":111.9},{"period":"16h38","value":111.8},{"period":"16h39","value":111.8},{"period":"16h40","value":111.9},{"period":"16h41","value":111.9},{"period":"16h42","value":111.8},{"period":"16h43","value":111.9},{"period":"16h44","value":112},{"period":"16h45","value":112.1},{"period":"16h46","value":112.1},{"period":"16h47","value":112.1},{"period":"16h48","value":112},{"period":"16h49","value":111.9},{"period":"16h50","value":111.9},{"period":"16h51","value":112},{"period":"16h52","value":111.9},{"period":"16h53","value":111.9},{"period":"16h54","value":111.9},{"period":"16h55","value":111.9},{"period":"16h56","value":111.9},{"period":"16h57","value":112},{"period":"16h58","value":112},{"period":"16h59","value":112},{"period":"17h00","value":112.1},{"period":"17h01","value":112},{"period":"17h02","value":112.1},{"period":"17h03","value":112.1},{"period":"17h04","value":112.1},{"period":"17h05","value":112.2},{"period":"17h06","value":112.2},{"period":"17h07","value":112.3},{"period":"17h08","value":112.3},{"period":"17h09","value":112.4},{"period":"17h10","value":112.4},{"period":"17h11","value":112.4},{"period":"17h12","value":112.3},{"period":"17h13","value":112.3},{"period":"17h14","value":112.2},{"period":"17h15","value":112.2},{"period":"17h16","value":112.2},{"period":"17h17","value":112.2},{"period":"17h18","value":112.2},{"period":"17h19","value":112.2},{"period":"17h20","value":112.2},{"period":"17h21","value":112.2},{"period":"17h22","value":112},{"period":"17h23","value":112.1},{"period":"17h24","value":112.1},{"period":"17h25","value":112.1},{"period":"17h26","value":112.1},{"period":"17h27","value":111.9},{"period":"17h28","value":111.8},{"period":"17h29","value":111.9},{"period":"17h30","value":111.9},{"period":"17h31","value":111.9},{"period":"17h32","value":111.9},{"period":"17h33","value":111.9},{"period":"17h34","value":111.9}]},"modifierClasses":"c-chart--height-xs"}}');
                                            var mergedConfig = $.extend(true, {}, chart.data.amChartConfig, chart.static.amChart);
                                            var elemSelector = mergedConfig.brs.id ? "#" + mergedConfig.brs.id : '[data-line-chart]';
                                            $(elemSelector).amCharts(mergedConfig, chart.data.amChartData);
                                        });

but that dos not look like what I get if I click on “5J” so I am wondering where the data are available :
enter image description here

why undefined site, which is a returned variable from a function of Exif?

I have a problem about “undefined site(a returned variable)”.
The code is attached.

The code is simple to get geolocation from a geotagged images through Exif library.
getExif() is a function to return a variable “site” whose type is google.maps.LatLng.
But somehow the returned value is undefined.
Weird is that some console.log() in the function is put at the end of the program,
even after console.log(“xxxxxxxxxxxxxxxx”), which is called way after the function.

Also I have tested by defining getExif2(); which simply returns a fixed value of google.maps.LatLng.
This works fine and returns the fixed value.
I think the fundamental difference between getExif() and getExif2() is calling Exif function or not.
I am suspecting exif function takes time because it processes a image file; the program goes next
without waiting the function finished. That is why the order of function has been changed, i.e. console.log(“xxxxxxxx”) is executed earlier and the variable “site” has not been set yet.

Any help would be appreciated.
Developped on Firefox 113.0.2 (Ubuntu 20.04).

Warm Regards,

DoKtor.

Geotagged image: please download below and save as ./london-bridge.jpg.
https://www.geoimgr.com/images/samples/england-london-bridge.jpg

Note: a google API key is set in my real script.

Code:
test_stackoverflow20240808.html

<!Doctype html>
<head>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?callback=initMap&loading=async"></script>

<script src="https://cdn.jsdelivr.net/npm/exif-js"></script>
<script type="text/javascript">
<!--header("Access-Control-Allow-Origin: *");-->

var Gsite;
var site;
var sites = [];

  function getExif(image) { // image as Image().src = "./image.jpg";
    console.log("getExif() called");
    console.log("getExif() called with: "+ image.src);
    var site = new google.maps.LatLng(0,0);
    console.log("site: "+site);
    //return site;
    EXIF.getData(image, function() {
        myData=this;
        var make = EXIF.getTag(this, "Make");
        var model = EXIF.getTag(this, "Model");
        var makeAndModel = document.getElementById("makeAndModel");
        makeAndModel.innerHTML = `${make} ${model}`;
        console.log("makeAndModel: "+ make + " " + model);

            // get latitude from exif data and calculate latitude decimal
            var latDegree = myData.exifdata.GPSLatitude[0].numerator;
            var latMinute = myData.exifdata.GPSLatitude[1].numerator;
            var latSecond = myData.exifdata.GPSLatitude[2].numerator;
            var latDirection = myData.exifdata.GPSLatitudeRef;

            var latFinal = ConvertDMSToDD(latDegree, latMinute, latSecond, latDirection);
        lat=latFinal;
        console.log("latFinal: "+latFinal);

            // get longitude from exif data and calculate longitude decimal
            var lonDegree = myData.exifdata.GPSLongitude[0].numerator;
            var lonMinute = myData.exifdata.GPSLongitude[1].numerator;
            var lonSecond = myData.exifdata.GPSLongitude[2].numerator;
            var lonDirection = myData.exifdata.GPSLongitudeRef;

            var lonFinal = ConvertDMSToDD(lonDegree, lonMinute, lonSecond, lonDirection);
        lng=lonFinal;
        console.log("lonFinal: "+lonFinal);


            site = new google.maps.LatLng(latFinal, lonFinal);
            console.log(site);
            //sites.push(site);

            return(site);

     });


}

function ConvertDMSToDD(degrees, minutes, seconds, direction) {
  var dd = degrees + (minutes/60) + (seconds/360000);
  if (direction == "S" || direction == "W") {
   dd = dd * -1;
  }
  return dd;
}


function getExif2(image) {
   site = new google.maps.LatLng(50.0, 60.0);
   console.log(site);
   sites.push(site);
   return(site);
}


function initialize() {
    console.log("initialize() called.");
    var img1 = document.getElementById("img1");
    console.log("img1: "+img1);

    Gsite=getExif(img1);
    console.log("img1 site: "+Gsite);
    console.log("xxxxxxxxxxxxxxxxxxxxxxxxxx");

    Gsite=getExif2(img1);
    console.log("img1 site: "+Gsite);
    console.log("yyyyyyyyyyyyyyyyyyyyyyyyyy");
}

function initMap() {
console.log("initMap called.");
initialize();
}

</script>

  </head>
  <!--<body onload="initialize()">-->
  <body>
  <img width=300 id="img1" src="london-bridge.jpg" />

<pre>Make and model: <span id="makeAndModel"></span></pre>
<br/>

</body>
</html>

Prop is not giving effect

This is my react component

const ButtonComponent = ({ children, onClick, disabled, className = "" }) => {
  console.log("class name is ", className);

  const buttonClassName = `
    bg-green-700 
    flex 
    hover:bg-green-500 
    transition 
    duration-300 
    ease-in-out 
    text-white 
    h-auto 
    text-base 
    p-2 
    rounded-[5px] 
    m-2 
    ${
      disabled
        ? "bg-teal-200 text-teal-800 cursor-not-allowed"
        : "cursor-pointer"
    } 
    ${className}
  `;

  return (
    <button onClick={onClick} className={buttonClassName} disabled={disabled}>
      {children}
    </button>
  );
};

export default ButtonComponent;

The console.log is working properly, but in the JSX, the className prop is not giving right value.