Insert a dynamically generated image from JavaScript into a Google Sheet cell

I’ve got some client-side javascript that generates an image based on passed in parameters, like so:

https://medabots.github.io/medarot3_dialog-previewer-js/?t=%3C%40LL%2C00%2C04%3EIt%27s%20a%20vending%20machine%20that%20sells%20ice%20cream.%3CCF%3E%3C%40LL%2C00%2C04%3EPudding%20ice%20cream…!%3CCF%3E%3C%40LL%2C00%2C04%3ENah...

the generated image

It uses the Canvas API to draw the image.

However, this does not seem to work within Google Sheets. I’d like to take advantage of GitHub pages or Google Sheets such that I don’t need to host this image generation tool on a personally-hosted server.

Specifically, I’ve tried:

=IMAGE(CONCAT("https://medabots.github.io/medarot3_dialog-previewer-js/?t=", ENCODEURL("<%40LL%2C00%2C04>It's a vending machine that sells ice cream.<CF><%40LL%2C00%2C04>Pudding ice cream...!<CF><%40LL%2C00%2C04>Nah...")))

and it doesn’t seem to load at all.

A PHP implementation running on an external server works fine, but I assume this is because an image is being pre-generated and served to the client without any hassle…

Is there any solution that can work with Google Sheets such that I don’t need to host the preview tool myself (e.g. doing this within AppScript)? Or is a hosted solution the only feasible answer?

JavaScript: Clean way to set/remove a bool attribute

With Javascript I often have to do something like this:

   if (predicate) el.setAttribute('data-foo', '')
   else el.removeAttribute('data-foo')

what I would really like to do is this (nice and DRY):

   el.setBoolAttribute('data-foo', predicate)  // Desired function

Its a function I would like to use in the DOM, and web component shadow roots, in many places, so its not really a function I would like to import from a module. Does Javascript have any sort of native way?

Getting Error -uncaught TypeError Cannot read properties of undefined reading

<script type="text/javascript
src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

<script type="text/javascript">  


$(document).ready(function () {
$.ajax({
type: "Get", url: "https://eduteksolutions.in//info//AcademicMaster?instituteCd=29", dataType: "json", contentType: "application/json",

data: "{}",
success: function (data) {
var s = '<option value="-1">Please Select a Department</option>';
for (var i = 0; i < data.length; i++) {
s += '<option value="' + data[i].ClassCd + '">' + data[i].ClassName + '</option>';
}
$("#ctl00_center_ddlNationality").html(s);
}
});
});  
});

its giving Error message Uncaught TypeError Can Read Proeperties of undefined Caught.plz provide any solutions reading.`

Agora-RTC-React: client.remoteUsers behaving unexpectedly

So, I have a video call channel where two users can connect. I’m checking the number of connected users by checking the length of client.remoteUsers array. The problem is, that when one of the users refreshes the video call page, then instead of returning 2, it returns me 3.

In my code, I only show the video screen when the length of client.remoteUsers array is 2. But, I’m perplexed by this unexpected behavior. Can anyone please help? Thanks.

Reference code:

client.on("user-published", async (user, mediaType) => {
          console.log(user, "agoramiccc")
          await client.subscribe(user, mediaType);
          // console.log("subscribe success");          
          if (mediaType === "video") {
            if (!users.length) {
              setUsers((prevUsers) => {
                return [user];
              });
            }
          }
          if (mediaType === "audio") {
            user.audioTrack?.play();
          }
        });



        client.on("user-unpublished", (user, type) => {
          console.log(user, "unpub")

          // console.log("unpublished", user, type);
          if (type === "audio") {
            user.audioTrack?.stop();
          }
          if (type === "video") {
            setUsers((prevUsers) => {
              return prevUsers.filter((User) => User.uid !== user.uid);
            });
          }
        });
        client.on("user-left", (user) => {
          // console.log("leaving", user);
          setUsers((prevUsers) => {
            return prevUsers.filter((User) => User.uid !== user.uid);
          });
        });
        await client.join(config.appId, name, config?.token, null);
        if (tracks) await client.publish([tracks[0], tracks[1]]);
        setStart(true);
      };

Upload file in chunk with react and node not working

I am working with React and Nodejs. And we have scenerio where we have to upload 10gb of file on the aws. I know that cannot be possible with single request and that is why I devided it into chunks but still it is not working and throw error after couple of chunk uploads. Here is the code

Frontend

import React, { useState, useEffect } from "react";
import { UploadDropzone } from "../../../components/icons";
import { Progress } from "antd";
import Dropzone from "react-dropzone";
import axios from "axios";
import { notification } from "antd";
import { isEmptyArray } from "formik";

const chunkSize = 1048576 * 25;

function UploadLocalVideo(props) {
  const { setUploadUrl, storageId, acceptFileType, isResourceBucket, callBackFun } = props;
  const [progress, setProgress] = useState(0);
  const [beginingOfTheChunk, setBeginingOfTheChunk] = useState(0);
  const [endOfTheChunk, setEndOfTheChunk] = useState(chunkSize);
  const [fileToBeUpload, setFileToBeUpload] = useState({});
  const [progressUpload, setProgressUpload] = useState(0);
  const [fileSize, setFileSize] = useState(0);
  const [chunkCount, setChunkCount] = useState(0);
  const [uploadId, setUploadId] = useState("");
  const [name, setName] = useState("");
  const [parts, setParts] = useState([]);
  const [counter, setCounter] = useState(1);
  const [percent, setPercent] = useState(0);
  const [fileType, setFileType] = useState("");
  const [uploading, setUploading] = useState(false);
  const onUpload = async (files) => {
    if (!isEmptyArray(files)) {
      setUploading(true);
    }
    let percent = 0;
    let name = Math.random().toString(36).substring(2, 10);
    resetChunkProperties();
    const _file = files[0];
    name = (name + _file?.name?.replace(/ +/g, "")).replace(/[{()}]/g, "");
    setName(name);
    setFileType(_file.type);
    setFileSize(_file.size);

    const _totalCount = _file.size % chunkSize == 0 ? _file.size / chunkSize : Math.floor(_file.size / chunkSize) + 1;
    setChunkCount(_totalCount);
    percent = 100 / _totalCount;
    setPercent(percent);
    setFileToBeUpload(_file);
    setProgress(1);
  };

  const resetChunkProperties = () => {
    setProgressUpload(0);
    setCounter(1);
    setBeginingOfTheChunk(0);
    setEndOfTheChunk(chunkSize);
    setUploadId("");
    setName("");
    setParts([]);
    setPercent(0);
    setProgress(0);
    setFileType("");
  };
  useEffect(() => {
    if (fileSize > 0) {
      fileUpload(counter);
    }
  }, [fileToBeUpload, progressUpload]);

  const fileUpload = () => {
    setCounter(counter + 1);
    if (counter <= chunkCount) {
      var chunk = fileToBeUpload.slice(beginingOfTheChunk, endOfTheChunk);
      uploadChunk(chunk);
    }
  };

  const uploadChunk = async (chunk) => {
    try {
      const formData = new FormData();
      formData.append("file", chunk);
      formData.append("name", name);
      formData.append("fileType", fileType);
      formData.append("chunkSize", chunk.size);
      formData.append("currentIndex", counter);
      formData.append("totalChunk", chunkCount);
      formData.append("uploadId", uploadId);
      formData.append("EtagArray", JSON.stringify(parts));
      formData.append("storageId", storageId);
      formData.append("isResourceBucket", isResourceBucket);
      await axios({
        method: "post",
        url: `${process.env.REACT_APP_NEW_API_HOSTNAME}/upload-chunk`,
        data: formData,
      }).then((response) => {
        if (response.data.uploadStatus == "uploading") {
          setBeginingOfTheChunk(endOfTheChunk);
          setEndOfTheChunk(endOfTheChunk + chunkSize);
          setUploadId(response.data.uploadId);
          setParts([...parts, response.data.etag]);
          setProgress(parseInt((progressUpload + 1) * percent));
          setProgressUpload(progressUpload + 1);
        } else if (response.data.uploadStatus == "complete") {
          setUploadUrl(response.data.url); // set url or response url
          callBackFun(fileToBeUpload);
          setProgress(100);
          setUploading(false);
        } else if (response.data.uploadStatus == "failed" || response.data.status == false) {
          notification["error"]({ message: response.data.message });
          setProgress(0);
          setUploading(false);
        } else if (response.data.success == false) {
          notification["error"]({ message: "Storage not found" });
          setProgress(0);
          setUploading(false);
        }
      });
    } catch (error) {
      console.log(error, "error");
    }
  };
  return (
    <div className="form-group">
      <Dropzone
        onDrop={(acceptedFiles) => {
          onUpload(acceptedFiles);
        }}
        accept={acceptFileType}
        disabled={uploading}
      >
        {({ getRootProps, getInputProps }) => (
          <div className="dropzone">
            <div className="dropzone-inner" {...getRootProps()}>
              <input {...getInputProps()} />
              <div className="dropzone-icon">
                <UploadDropzone />
              </div>
              <div className="dropzone-title">Upload a File</div>
              <div className="dropzone-subtitle">
                Click to <u>browse</u>, or drag & drop your file here
              </div>
              <Progress strokeLinecap="butt" type="line" percent={progress} /> {progress > 1 ? `${progress} %` : ""}
            </div>
          </div>
        )}
      </Dropzone>
    </div>
  );
}

export default UploadLocalVideo;

Backend

const handler = async (request, reply) => {
    try {
        let uploadId = (_.get(request.payload, "uploadId", ""));
        let fileName = (_.get(request.payload, "name", ""));
        let multiParts = JSON.parse(_.get(request.payload, "EtagArray", []))
        let storageId = _.get(request, "payload.storageId", "")
        let dataBuffer = Buffer.from(request.payload.file)
        let currentChunkIndex = parseInt(request.payload.currentIndex);
        let totalChunk = parseInt(request.payload.totalChunk);
        let isResourceBucket = JSON.parse(_.get(request, "payload.isResourceBucket", false))
        let region = ""
        let credentials = {}
        let squery = {
            name: { $in: ["aws"] }
        }
        if (isResourceBucket && storageId == "") {
            squery._id = mongoose.Types.ObjectId("62e112750e3d4dada1b9a3c0")
        } else {
            squery._id = mongoose.Types.ObjectId(storageId)
        }

        if (currentChunkIndex <= totalChunk) {
            let storages = await Storage.findOne(squery)
            if (storages && storages.credentials) {
                credentials = await StreamService.decrypt_storage_credentials(storages.credentials, 'aws')
                region = (credentials.region).replace("s3.", "").replace(".amazonaws.com", "").replace("s3-", "")
            } else {
                return reply({
                    status: false,
                    message: 'Storage not found',
                    uploadStatus: "failed"
                })
            }
        }
        AWS.config.update({
            accessKeyId: credentials.access_key,
            secretAccessKey: credentials.secret_key,
            region: region
        })

        const s3 = new AWS.S3({
            params: {
                Bucket: credentials.bucket_name,
            },
            // endpoint,
            signatureVersion: 'v4',
            region: region,
            apiVersion: '2006-03-01'
        })

        let filename = `uploadFile/${fileName}`;

        if (currentChunkIndex == 1) {
            uploadId = await getUploadId(filename, s3, credentials.bucket_name)
            console.log("currentChunkIndex", " == ", currentChunkIndex, { uploadId })
        }

        if (currentChunkIndex < totalChunk) {
            let etag = await uploadParts(filename, credentials.bucket_name, dataBuffer, currentChunkIndex, uploadId, s3)
            return reply({
                status: true,
                uploadId,
                etag,
                uploadStatus: "uploading",
                message: "uploading"
            })
        } else if (currentChunkIndex == totalChunk) {
            let finalChunk = await uploadParts(filename, credentials.bucket_name, dataBuffer, currentChunkIndex, uploadId, s3)
            let etag = { ETag: finalChunk.ETag, PartNumber: currentChunkIndex };
            multiParts.push(etag)
            let location = await completeFileMultiPartUpload(filename, credentials.bucket_name, uploadId, multiParts, s3, credentials.cdn_suffix);
            location = location.replace("%2F","/")
            console.log({ location })
            if (location) {
                return reply({
                    status: true,
                    url: location,
                    uploadStatus: "complete",
                    message: "upload completed"
                })
            }
        }
    } catch (error) {
        logger.error(error)
        return reply({
            success: false,
            message: error.message
        });
    }
};

These are the logs

enter image description here
So I have couple of question. 1. When we upload the 10gb file does it consumes node memory? if “Yes” then what is the solution?

Thanks

Update value in array inside array in javascript [duplicate]

I have a array as follows

data = [
{
 sNo:1,
 month:[
 {
  id:1,
  value:0
 },
  id:5,
  value:10
 },
 {
 sNo:2,
 month:[
 {
  id:6,
  value:10
 },
  id:9,
  value:20
 }
]

I have a method as follows:

myMethod(value,sNo,indexOfMonthArray) {

}

this method receives three aruguments. one is value to be updated, second is sNo and third is index of inner month array where value needs to be updated. I want to search of sNo in data array and for that particular sNo, in month array I need to update value which I am recieving in argument. How can I do that?

how to send mail using nodemailer and nodemailer not working mail not send

*** my nodemailer not working and mail not send got error***

const model = require("./usermodel")
const nodemailer = require("nodemailer")
const randomstring = require("randomstring")
const emailUser = process.env.emailUser
const emailpassword = process.env.emailpassword
const sendmail = async (name, email, token) => {
    const transpoter = nodemailer.createTransport({
        host: 'smtp.gmail.com',
        port: 587,
        secure: false,
        requireTLS: true,
        auth: {
            user: emailUser,
            pass: emailpassword
        }
    })
    const mailoption = {
        from: emailUser,
        to: email,
        subject: "reset password",
        html: '<p>hii' + name + ' ,copy link and <a href = "http://localhost:3000/reset-password ' + token + '">reset your password</a>'
    }
    transpoter.sendMail(mailoption, (error, inform) => {
        if (error) {
            console.log("error")
        } else {
            console.log("mail is send to email", inform.response);
        }
    })
}

const userregister = async (req, res) => {
    let body = req.body
    let create = await model.create(body)
    res.send(create)
}
const forgotpasswrod = async (req, res) => {
    const email = req.body.email
    const userdata = await model.findOne({ email: email })
    if (userdata) {
        const radonstring = randomstring.generate()
        const data = await model.updateOne({ email: email }, { $set: { token: radonstring } })
        sendmail(userdata.name, userdata.email, radonstring)
        res.send({ message: "please check your mail" })
    } else {
        return res.send({ message: "email not found" })
    }
}

module.exports = { userregister, forgotpasswrod }





*** env file 

emailUser =”
emailpassword = ” ****
*** mail not sending to user fix i am try to lot of time but mail not sending to user so when i try to send mail to user mail not send user ***

Why is my dropdown list showing differently on phone than desktop and how can I fix it?

I have a normal select/option setup for a dropdown list and on desktop it looks like normal: https://imgur.com/6xaHjjd.

However, on the phone it instead uses some native phone list, something that looks like this: https://imgur.com/Avftd0N.

This could be all fine, the problem is that in some places I have made my own multi select dropdown list which looks like this: https://imgur.com/2n8SnsL. This list will show like this on both desktop and phone, since it is just made up of divs.

Questions

  1. Can I somehow force all devices to use the same type of dropdown on a normal select/option setup?
  2. Should I?
  3. If not, would you recommend me to create my own dropdown lists too so that I get the same behaviour for both normal and multiple select dropdown lists? It is sort of ugle when one dropdown shows as e.g. native android and one as a “normal” dropdown on the phone.

javascript const = “filepath” for react project

Full disclosure i have done some Google searching on this but i’m aware i may not be asking the correct questions to find what i’m looking for.

I’m using a react template found on Github for an internal application for work that i intend to utilize for searching a json file.

link for reference – Link

the source file in the example is like this:

const initialDetails = [
  {
    id: 1,
    imgPath: "/assets/img/1.png",
    name: "Jane Doe",
    email: "[email protected]",
    address: "New Delhi, India",
  },
  {
    id: 2,
    imgPath: "/assets/img/2.png",
    name: "Mary Rosamund",
    email: "[email protected]",
    address: "Tbilisi, India",
  },
  {
    id: 3,
    imgPath: "/assets/img/3.png",
    name: "Sherlock Watson",
    email: "[email protected]",
    address: "Baker Street, India",
  },
  {
    id: 4,
    imgPath: "/assets/img/4.png",
    name: "John Holmes",
    email: "[email protected]",
    address: "Baker Street, India",
  },
  {
    id: 5,
    imgPath: "/assets/img/5.png",
    name: "Mycroft Lestrade",
    email: "[email protected]",
    address: "London, India",
  },
];

export default initialDetails;

What i would like to is for the equivalent of const initialDetails = “jsonFilePath”

The file i need to query is updated once a minute.

What is the standard way to perform this type of function?

As i’ve stated, i may not be asking the correct questions needed to obtain this solution through Google so thats what led me here.

How to set error state for MUI Textfield without creating a state variable

I currently have 10+ input fields that require form validation against empty user input. It seems the conventional route is to create a state variable to handle this:

const [error, triggerError] = React.useState(false)

and trigger it onSubmit if the value is empty

userInput === '' ? triggerError(true) : triggerError(false)

Issue

However, as the number of form elements scale, so too do these state variables, which is undesirable as it clutters the code. Is there a way to forcibly set the textfield to an error state from the onSubmit function or from the component itself?

Attempted Solutions

(1) From onSubmit: document.getElementById(e.target.id).error = true

(2) From the TextField component: error: {this.value === '' ? true : false}

Possible Solution?

For MUIv4, this is the inspect element output of getElementById(e.target.id):

MuiInputBase-root MuiOutlinedInput-root Mui-error Mui-error MuiInputBase-fullWidth MuiInputBase-formControl MuiInputBase-multiline MuiOutlinedInput-multiline MuiInputBase-marginDense MuiOutlinedInput-marginDense

Perhaps we can append the error CSS class to trigger the error from the onSubmit function?

Please let me know if I can clarify the question in any way and thanks in advance

how to estimate how much until the download will be finished and then show it on the site as a progression bar+ timer

“pretty much i know that i have to do it in java but i really don t know anything about java, only thing i knew how to do is how to make the page not freeze up during changes of the page, through AJAX

pretty much i wanted to challenge myself by implementing the yt-dlb fork for youtube, it works great but i got stuck at adding a timer that tells the user how much time until the converted file will be ready for downloading (what i mean by this is strictly, the time from when the users press convert until the button for them to download the said file appears.)

I don t plan on deploying this anywhere, i just wanna learn how to do it

i tried looking onto some forums but for no use

only thing i tried is this

<h1>Yeqwfwq</h1>

<div id="message"></div>

<form id="download-form">
    <label for="youtube_url">YouTube video URL:</label>
    <input type="text" name="youtube_url" id="youtube_url">
    <br><br>
    <label for="format">Select a format:</label>
    <select name="format" id="format">
        <option value="mp3">MP3</option>
        <option value="mp4">MP4</option>
    </select>
    <br><br>
    <button type="submit">Convert</button>
</form>

<div id="progress-bar" style="display:none">
    <div id="progress" style="background-color: #4CAF50; width: 0%; height: 20px;"></div>
    <div id="progress-text">Conversion progress: <span id="progress-percent">0%</span></div>
    <br>
</div>

<script>

    $(document).ready(function() {

        // Handle form submission
        $("#download-form").submit(function(event) {
            event.preventDefault();
            var form = $(this);
            var message = $("#message");
            var url = form.find("#youtube_url").val();
            var format = form.find("#format").val();

            // Check if the YouTube URL is valid
            if (url.trim() === "" || !isValidYoutubeUrl(url)) {
                message.html("Please enter a valid YouTube video URL");
                return;
            }

            // Send AJAX request to start download
            $.ajax({
                type: "POST",
                url: "download.php",
                data: {
                    youtube_url: url,
                    format: format
                },
                beforeSend: function() {
                    message.html("Starting download...");
                    $("#progress-bar").show();
                },
                xhr: function() {
                    var xhr = $.ajaxSettings.xhr();
                    if (xhr.upload) {
                        xhr.upload.addEventListener('progress', function(event) {
                            var percent = 0;
                            var position = event.loaded || event.position;
                            var total = event.total || event.totalSize;
                            if (event.lengthComputable) {
                                percent = Math.ceil(position / total * 100);
                            }
                            $("#progress").width(percent + '%');
                            $("#progress-percent").html(percent + '%');
                        }, true);
                    }
                    return xhr;
                },
                success: function(data) {
                    message.html(data);
                    $("#progress-bar").hide();
                },
                error: function() {
                    message.html("An error occurred while downloading the video");
                    $("#progress-bar").hide();
                }
            });
        });

        // Validate YouTube URL
        function isValidYoutubeUrl(url) {
            var pattern = /^(https?://)?(www.)?(youtube.com|youtu.be)//;
            return pattern.test(url);
        }

    });
</script>


but everytime i would try to download something, the timer would show after download is finished.

this would be the php code that does all the job

<?php

// Check if YouTube video URL and format are set
if (isset($_POST['youtube_url']) && isset($_POST['format'])) {

    // Get YouTube video URL and format
    $youtube_url = $_POST['youtube_url'];
    $format = $_POST['format'];

    // Validate YouTube URL
    if (preg_match('/^(https?://)?(www.)?(youtube.com|youtu.be)//', $youtube_url) !== 1) {
        die("Please enter a valid YouTube video URL");
    }

    // Build yt-dlp command
    $cmd = "yt-dlp --yes-playlist -o downloads/%(title)s.%(ext)s " . escapeshellarg($youtube_url);

    // If format is mp3, add the --extract-audio and --audio-format mp3 options
    if ($format === "mp3") {
        $cmd .= " --extract-audio --audio-format mp3";
    }

    // If format is mp4, add the --merge-output-format mp4 option
    if ($format === "mp4") {
        $cmd .= " --merge-output-format mp4";
    }

    // Execute yt-dlp command
    exec($cmd, $output, $return);

    // Check if the download was successful
    if ($return === 0) {
        // Find the downloaded file
        $files = glob('downloads/*.' . $format);
        if (count($files) > 0) {
            $filename = $files[0];
            // Set headers to download the file
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
            header('Content-Length: ' . filesize($filename));
        } else {
            echo "An error occurred: downloaded file not found";
        }
    } else {
        echo "An error occurred while downloading the video";
    }

    // Add download button
    echo '<a href="downloads/' . basename($filename) . '" download>
    <button>Download Converted File</button>
</a>';

} else {
    echo "Please enter a YouTube video URL and select a format";
}

?> 






and this would be the code that handles the HTML page


<!DOCTYPE html>
<link rel="stylesheet" href="style.css">
<html>
<head>
    <title>YouTube Downloader</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>

    <h1>YouTube Downloader</h1>

    <div id="message"></div>

    <form id="download-form">
        <label for="youtube_url">YouTube video URL:</label>
        <input type="text" name="youtube_url" id="youtube_url">
        <br><br>
        <label for="format">Select a format:</label>
        <select name="format" id="format">
            <option value="mp3">MP3</option>
            <option value="mp4">MP4</option>
        </select>
        <br><br>
        <button type="submit">Convert</button>
    </form>

    <script>

        $(document).ready(function() {

            // Handle form submission
            $("#download-form").submit(function(event) {
                event.preventDefault();
                var form = $(this);
                var message = $("#message");
                var url = form.find("#youtube_url").val();
                var format = form.find("#format").val();

                // Check if the YouTube URL is valid
                if (url.trim() === "" || !isValidYoutubeUrl(url)) {
                    message.html("Please enter a valid YouTube video URL");
                    return;
                }

                // Send AJAX request to start download
                $.ajax({
                    type: "POST",
                    url: "download.php",
                    data: {
                        youtube_url: url,
                        format: format
                    },
                    beforeSend: function() {
                        message.html("Starting download...");
                    },
                    success: function(data) {
                        message.html(data);
                    },
                    error: function() {
                        message.html("An error occurred while downloading the video");
                    }
                });
            });

            // Validate YouTube URL
            function isValidYoutubeUrl(url) {
                var pattern = /^(https?://)?(www.)?(youtube.com|youtu.be)//;
                return pattern.test(url);
            }

        });
    </script>

</body>
</html>



`

`

Import async vanilla js function into react component [duplicate]

I created a function that retun a city using public Ip address. Inside that function I get result but unable to get result into another react component.

getCity.js

const { publicIpv4 } = require("public-ip");
export async function currentCity() {
  let ip = "";
  let city = "";
  // Get IP
  try {
    ip = await publicIpv4();
  } catch (err) {
    console.log(err);
  }

  // Get City From Ip and save
  fetch(`https://ipapi.co/${ip}/json/`)
    .then(function (response) {
      response.json().then((jsonData) => {
        // console.log(jsonData.city);
        city = jsonData.city;
        // console.log(`city: ${city}`);
      });
    })
    .catch(function (error) {
      console.log(error);
    });

  return city;
}

WeatherCard.js

import React, { useState } from "react";
import { currentCity } from "./getCity";

const WeatherCard = () => {
  const [city, setCity] = useState("");

  setCity(currentCity());
  console.log(city);

  return <div></div>;
};

export default WeatherCard;

Use references/pointers to JS Array declared outside of function

I am writing a small tictactoe game in Angular.

I have a function checkForWin() which checks all the possible winning combinations for a win. (Horizontal, Vertical, and Diagonal)

The function works correctly when I declare/init potentialWinningCombos inside of checkForWin()

checkForWin(){
  for(let combo of potentialWinningCombos){  
    let potentialWinningCombos: string[][] = [
       //Horizontal
       [this.gb[0][0], this.gb[0][1], this.gb[0][2]],
       [this.gb[1][0], this.gb[1][1], this.gb[1][2]],
...

So that’s fine and all, but my original design was to declare/init potentialWinningCombos outside of checkForWin() (in the component — and of course I’d iterate over this.potentialWinningCombos instead of the local variable)

With this approach I always get empty strings (the initial values).

My original thought was that when I declare/init potentialWinningCombos with a reference to this.gb[0][0], then it would simply be a reference, but it seems that is not the case…

Why?
Additionally, is there any possible way to keep my original design (using a reference/pointer) so the object isn’t recreated everytime checkForWin() is called? (I know here it’s no big deal, but imagine another case where this is a massive object…)