Updating component state inside array.map() causing too many re-renders

import useState from "react-usestateref";

const [meta, setMeta, metaRef] = useState({});

Inside component’s JSX:

data.result.map((token) => {
                        const id = token.token_id;
                        const params = { uri: token.token_uri };

                        if (token.metadata) {
                            setMeta(JSON.parse(token.metadata));
                        } else {
                            Moralis.Cloud.run("get_token_uri", params).then(
                                (response) => setMeta(response)
                            );
                        }
                        const { name, description, imageUrl } = metaRef.current;
                        return (
                            <Card
                                key={id}
                                tokenId={id}
                                name={name}
                                description={description}
                                user_address={user_address}
                                imageUrl={fixURL(imageUrl)}
                                calledFrom={calledFrom}
                            />
                        );
                    })

I want to update the meta state variable from inside data.result.map and use the updated meta object to return a Card component. I’m using react-usestateref to get the current value of the meta state variable. Otherwise, meta still remains {} when de-structuring, even after being updated. If token.metadata is not null I want to set the meta state var to token.metadata obj and if it is null, I want to make an asynchronous request to get back the object from Moralis and then set it to the meta state var. This code is producing the following error: Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.

How can I make this code work as intended?

Why can’t the posts made by the user be displayed?

In the backend I can use my Token to search after Notes which User creates.
In my Frontend project it doesn´t show me my Posts ..

I store my token in localStorage “userInfo” .. so it can be taken from there if I login to my account.

my NotesSchema :

const forumSchema = ({
    forumName: {
        type: String,
        required: true,
    },
    forumDescription: {
        type: String,
        required: true,
    },
    createdBy: { 
        type: Schema.Types.ObjectId, ref: 'User' 
    },
    published_on: {
        type: String,
        default: moment().format("LLL")
    },
});

My note route :

router.get('/getByOwnerID',verifyToken,ForumService.getByToken);

And the function which I wrote for that :

exports.getByToken = async (req, res, next) => {
  Forum.find({ userID: req.token.userID }) 
  .then(doc => {
      if(!doc) { return res.status(400).end();}
      return res.status(200).json(doc);
  })
  .catch(err => next(err));
}

And the frontend noteAction.js:

export const listNotes = () => async (dispatch, getState) => {
    try{
        dispatch({
            type: NOTES_LIST_REQUEST,
        });
        const {
            userLogin: { userInfo },
        } = getState();

        const config = {
            headers: {
                Authorization: `Bearer ${userInfo.token}`,
            },
        };

        const { data } = await axios.get(`http://localhost:8080/forum/getByOwnerID`, config);
        
        dispatch({
            type: NOTES_LIST_SUCCESS,
            payload: data,

        });
        }catch(error){
            const message = 
                error.response && error.response.data.message
                    ? error.response.data.message
                    : error.message;
            dispatch({
                type: NOTES_LIST_FAIL,
                payload: message,
            });
        }
    }

I hope it´s clear if not I can add Information ..

Phaser-3: Is there a way to move an image from one location to another while the program is running and so it is visible doing so?

i would like to create a battle system for an rpg game ,where an opening animation plays showing the battling characters move from the side of the screen to a location on the screen. Current code, assets and current running view provided below;

<!doctype html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8" />
    <title>battle</title>
    <script src="phaser.js"></script>
    <style type="text/css">
        body {
            margin: 0;
        }
    </style>
</head>
<body>


<script type="text/javascript">
var config = {
    type: Phaser.AUTO,
    width: 1900,
    height: 900,
    physics: {
        default: 'arcade',
        arcade: {
            gravity: { y: 0},
            debug: false
        }
    },
    scene: {
        preload: preload,
        create: create,
        update: update,
        
        }
    };
var game = new Phaser.Game(config);

function preload(){ 
    this.load.image("background","assets/battle background.png");
    this.load.image("hydroBot","assets/water hydrant.png");
    
};
function create(){
    const battle = this.add.image(0,0,"background").setOrigin(0,0);
    const bot= this.add.image(1000,200,"hydroBot");
    bot.setScale(5);
   
    
};
function update(){

};

</script>
</body> 

water_hydrant/hydrobot

the battle background

the current view when running the code

much appreciated thanks 🙂

How to use XPath in a newly opened window?

With the code below, I am trying to open a new window, look for certain span-elements, and click each of them. However, I cannot access the code of the new window through XPath.

  • Inserting the code (copy & paste) of the clickElem function directly in the new tab works fine
  • CORS shouldn’t be a problem since it’s the same domain
  • I’ve been also following this answer.

JavaScript:

const w = window.open('https://example.com', 'Example', 'width=500, height=500');
w.clickElem = () => {
    const xpath = '//span[text()="Click here"]';
    const selectedNodeElements = w.document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null);
    let currentNode = selectedNodeElements.iterateNext();
    while (currentNode) {
        currentNode.click();
        currentNode = selectedNodeElements.iterateNext();
    }
}
setTimeout(w.clickElem, 8000);

When I try to access the text via currentNode.textContent I receive following error:

"Error in protected function: Cannot read properties of null (reading 'textContent')"

Grateful for every hint!

JavaScript POST non-API request with repeated keys in payload

Javascript. POST request. It is not an API request (axios or fetch), but the old classical request.

I need a payload like ...&_selected_action=5&_selected_action=10.
So I think I cannot use a form submitting technique here.
With a single occurence ...&_selected_action=5 I am able to do it, everything works well.
For the repeated value I can create the string by hand or by URLSearchParams().toString() but I am not able to send it.

Any idea?

More details. I need create this request in Django+Vue application which partially replaces the old school Django Admin. The ListView is replaced using Vue and now I want to reuse the actions where Django Admin uses Post request formatted as above. So with single selected row in list I am able to do it, but with 2+ selected rows I cannot find a good way how to do it.

Cannot access ‘usagePrice’ before initialization

I have a script that I’m using to calculate the price of a selected field

When i run the function ‘calculateTotal()’ i get this error “Cannot access ‘usagePrice’ before initialization”.

Here is my code:

// Returns total for step 1
const usagePrice = () => {
    const field = document.querySelector('input[name="usage"]:checked');
    const subField = document.querySelector('input[name="varifocal-lenses"]:checked');

    let price = field.dataset.price;
       

    if (field.value == 'varifocal') {
        
        price = subField.dataset.price;
    }

    console.log('Usage price: ' + price);
    return price;
}

// Adds all totals together
const calculateTotal = () => {
    const usagePrice = usagePrice();
    const prescriptionPrice = prescriptionPrice();
    const lensPackagePrice = lensPackagePrice();
    const lensTypePrice = lensTypePrice();

    const total = usagePrice + prescriptionPrice + lensPackagePrice + lensTypePrice;

    return total;
}


console.log(calculateTotal());

Can anyone explain whats going wrong? Thank you in advance.

How can I set data createContext?

HOW CAN I SET DATA INTO THE STATE?

** And how can i solve createContext error? **

export const LastChanceContext = createContext() //in there return error: Expected 1 arguments, but got 0.

export const GET_LASTCHANCE = “GET_LASTCHANCE”

const LastChanceWrapper = ({children} : {children:any}) => {

const initialState = {
    lastChances: [],
    lastChance: {}
};
console.log('asd',initialState);

const [state, dispatch] = useReducer(lastChanceReducer, initialState);

useEffect(() => {
    const getLastChance = async () => {
        const result = await axiosFetch('http://65.21.148.176:2803/api/Home/Get');
        const action = {
            type:GET_LASTCHANCE,
            payload:result.data.data.lastChanceList
        };
        if(Object.keys(result).length !== 0) {
             dispatch(
                 {state,
                action}
             )

            console.log(result.data.data.lastChanceList);
        }

    };

    getLastChance();
}, [])


return (
    <LastChanceContext.Provider value={{
        lastChances: state.lastChances,
        lastChance: state.lastChance
    }}>
        {children}
    </LastChanceContext.Provider>
)

}

export default LastChanceWrapper

JavaScript pre-allocated array Uncaught RangeError: Invalid Array Length

I have a small loop of code which is throwing Uncaught RangeError: Invalid Array Length

I was able to reproduce it with just this in the Google Chrome console

const COUNT = 100_000_000;
const xValues = new Array(COUNT);
const yValues = new Array(COUNT);
for (let i = 0; i < COUNT; i++) {
    xValues[i] = i;
    yValues[i] = Math.sin(i * 0.000001);
}
console.log(`count: ${yValues.length}`);

Here’s the output in developer console

enter image description here

As far as I know the maximum array size in Javascript is 2^32-1? There should be enough memory to allocate here and the index i is never negative or outside the bounds of the array as far as I can see.

Curiously enough, if I use this code, there is no crash

const COUNT = 100_000_000;
const xValues = new Array(COUNT);
const yValues = new Array(COUNT);
for (let i = 0; i < COUNT; i++) {
    xValues[i] = i;
    yValues[i] = i;
}
console.log(`count: ${yValues.length}`);

enter image description here

The value assigned to yValues[i] never goes outiside of the range -1, +1 so I can’t see this as a number out of range problem either.

Anyone shed any light on this?

How to loop over again an array when it finishes? JavaScript

Here is my code:

useEffect(() => {
    playerRef.current.seekTo(convertedflat[currentTimeIndex], 'seconds');
  });
  return (
    <>
      <main>
        <div className={style.main_container}>
          <NavBar />

          <div className={style.heronext}>
            <div className={style.hero_container}>
              <ReactPlayer
                ref={playerRef}
                playing
                controls={true}
                url={`videos/${episList[currentEpisodeIndex]}.mkv`}
                width="90%"
                height="55rem"
                />
               </div>

              <button
              className={style.next}
              onClick={() => {
                setCurrentTimeIndex((prevTimeIndex) => prevTimeIndex + 1) %
                  convertedflat.length;

                setcurrentEpisodeIndex((prevTimeIndex) => prevTimeIndex + 1) %
                  convertedflat.length;

                console.log(currentTimeIndex);
                console.log(currentEpisodeIndex);
              }}
            >
              Next
            </button>

basically when you click on the next button it moves to the next timestamp until the array finishes. but I want to it starts again when the array list is finished.Currently when the array navigation is finished it shows error.

I used % length but it doesnt work.
Here is the error message when the list is finished:

TypeError: Failed to set the ‘currentTime’ property on ‘HTMLMediaElement’: The provided double value is non-finite.

Blob file not open in Edge browser on Iphone IOS mobile

Hi All I am not able to dowonload PDF file on Iphone edge browser below is my code snippet in angular.

    const fileName = file.name + '.' + file.data_type;
      const dataType = res.type;
      const binaryData = [];
      binaryData.push(res);
      const blob = new Blob(binaryData, { type: 'application/pdf'});
      // IE
      if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveOrOpenBlob(blob, fileName);
      } else {
        // other browser
        const downloadLink = document.createElement('a');
        const url = window.URL.createObjectURL(blob);
        document.body.appendChild(downloadLink);
        downloadLink.href = url;
        downloadLink.target = '_blank';
        downloadLink.download = fileName;
        downloadLink.click();
       
      }

It is working on all other browser and devic.Not only working on Edge browser of Iphone

How to render only one component after changing the state from api?

I’m trying to create an interface to be able to monitor the outputs of a relay board.
When the page is loaded, the status of the output is set by changing the image of the component. I want read the status of the outputs every 1 second and update the relative component.
If I open another tab where I go to change the status of the output automatically I have to change the status of the first tab as well.
I don’t know how to make react render only the component that has changed

import React, { useState, useEffect } from 'react'
import EventBus from "../common/EventBus";
import api from "../services/api";
import Device from "../components/Device"
const serverLink = "http://localhost:8080";

const Devices = () => {
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(false);
    const [errorCode, setErrorCode] = useState("")
    const [state, setState] = useState()
    const [refreshInterval, setRefreshInterval] = useState(4000)
    async function setDevice(_id, outId, value) {
        try {
            const response = await api({ url: `${serverLink}/api/device/setdevice`, method: "POST", data: { _id: _id, outId: outId, value: value } })
            if (response.data.status === "error") {
                setError(true)
                setErrorCode(response.data.description)
                setLoading(false)
            }
        } catch (error) {
            const _content =
                (error.response &&
                    error.response.data &&
                    error.response.data.message) ||
                error.message ||
                error.toString();
            setErrorCode(_content);
            if (error.response && error.response.status === 403) {
                EventBus.dispatch("logout");
            }
        }
    }
    async function getStatus() {
        try {
            const response = await api.get(`${serverLink}/api/device/getstatus`)
            if (response.data.status === "error") {
                setError(true)
                setErrorCode(response.data.description)
                setLoading(false)
            } else {
                setState(response.data.data)
                setLoading(false)
            }
        } catch (error) {
            const _content =
                (error.response &&
                    error.response.data &&
                    error.response.data.message) ||
                error.message ||
                error.toString();
            setErrorCode(_content);
            if (error.response && error.response.status === 403) {
                EventBus.dispatch("logout");
            }
        }
    }

     useEffect(() => {
         getStatus()
         const interval = setInterval(getStatus, refreshInterval)
         return () => clearInterval(interval);
     }, []);
    return (
        <div className='conteiner-rw'>
            {loading ? "caricamento..." : error ? <p>{errorCode}</p> :(
                state.map((dev) => {
                    return dev.out.map((el, index) => {
                        return <Device key={index} {...el} _id={dev._id} setDevice={setDevice} />
                    })
                }))
            }
        </div>
    )
}

export default Devices

The device component

import React, { useState, useEffect } from 'react';
import image from "../assets/image/image"

const Device = ({ id, _id, name, type, value, setDevice }) => {
    const [state, setState] = useState(value)
    const changeState = () => {
        if (state == 1) {
            setState(0)
            setDevice(_id, id, 0)
        } else if (state == 0) {
            setState(1)
            setDevice(_id, id, 1)
        }

    }

    return (
        <div className='device conteiner-cl' onClick={() => changeState()}>
            <img src={state == 1 ? image.lamp_on : image.lamp_off} alt={name} className='icon' />
            {
                name
            }
        </div>

    )
}

export default Device

The api response

{
    "status": "ok",
    "data": [
        {
            "_id": "619e17af1479f1846c8afaee",
            "name": "dev1",
            "ip": "192.168.0.50",
            "descr": "denkovi",
            "channel": "",
            "type": "denkovi",
             "out": [
                {"id": 1,"name": "output1","value": "0"},
                {"id": 2,"name": "output2","value": "0"},
                {"id": 3,"name": "output3","value": "0"},
                {"id": 4,"name": "output4","value": "0"},
                {"id": 5,"name": "output5","value": "0"},
                {"id": 6,"name": "output6","value": "0"},
                {"id": 7,"name": "output7","value": "0"},
                {"id": 8,"name": "output8","value": "0"},
                {"id": 9,"name": "output9","value": "0"},
                {"id": 10,"name": "output10","value": "0"},
                {"id": 11,"name": "output11","value": "0"},
                {"id": 12,"name": "output12","value": "0"},
                {"id": 13,"name": "output13","value": "0"},
                {"id": 14,"name": "output14","value": "0"},
                {"id": 15,"name": "output15","value": "0"},
                {"id": 16,"name": "output16","value": "0"}
                        ]
        },
        {
            "_id": "619e17af1479f1846c8afaef",
            "name": "dev2",
            "ip": "192.168.0.50",
            "descr": "denkovi",
            "channel": "",
            "type": "denkovi",
            "out": [
                {"id": 1,"name": "output1","value": "0"},
                {"id": 2,"name": "output2","value": "0"},
                {"id": 3,"name": "output3","value": "0"},
                {"id": 4,"name": "output4","value": "0"},
                {"id": 5,"name": "output5","value": "0"},
                {"id": 6,"name": "output6","value": "0"},
                {"id": 7,"name": "output7","value": "0"},
                {"id": 8,"name": "output8","value": "0"},
                {"id": 9,"name": "output9","value": "0"},
                {"id": 10,"name": "output10","value": "0"},
                {"id": 11,"name": "output11","value": "0"},
                {"id": 12,"name": "output12","value": "0"},
                {"id": 13,"name": "output13","value": "0"},
                {"id": 14,"name": "output14","value": "0"},
                {"id": 15,"name": "output15","value": "0"},
                {"id": 16,"name": "output16","value": "0"}
            ]
        }
    ]
}

Detect if the position of a div crosses the center of the viewport

I am trying to observe and detect if the position of a div crosses the center of my viewport on the y-axis. If so a function should be fired.
I am not scrolling or dragging the element so I can’t use an event listener that listen to those events.
Does anyone know an approach that I could follow?
Please no jQuery solutions, I am using Vue3 so I would wan’t to use plain javascript.