‘react-google-maps’ Markers keeps showing although the array is empty

I am using react-google-maps within my GoogleMapComponent.js. This component should render multiple markers based on a prop called similarLocations. At initial render, the array is empty, and no markers are shown on the map. Inside the parent component, when the user inputs any character, a fetch request is triggered, which responds with an array of similar locations that is passed to the GoogleMapComponent, and the markers are successfully displayed on the map.

However, when the user inputs another character that results in an empty array response, the previous markers continue to be displayed on the map, even though I have confirmed that the prop is being passed with an empty array. How can I remove the markers when the array is empty?
Here’s the parent component CreateLocation.js :

            import React, { useEffect, useState } from 'react'
            import Input from '../../../components/input'
            import { checkLocationMatches} from '../api'
            import GoogleMapComponent from './GoogleMapComponent'


            const CreateLocation = ({
                isEdit,
            }) => {
                const [locationData, setLocationData] = useState({
                    id: null,
                    client: null,
                    locationName: '',
                    googleLocationDetails: '',
                    nameAr: '',
                    nameEn: '',
                    street: '',
                    description: '',
                    category: null,
                    clientCode: '',
                    tags: [],
                    lat: 0,
                    lang: 0,
                    gov: '',
                    city: '',
                    area: ''
                })
                const [similarLocations, setSimilarLocations] = useState([])

                const matchArabicName = async () => {
                    try {
                        const data = {
                            lat: locationData.lat,
                            lang: locationData.lang,
                            clientId: locationData.client.value,
                            matcher: 'name_ar',
                            name: locationData.nameAr
                        }
                        const response = await checkLocationMatches(data)
                        response.data ? setSimilarLocations(response.data) : setSimilarLocations([])
                    } catch (err) {
                        console.log(err.response, 'match err')
                    }
                }


                useEffect(() => {
                    if (locationData.lat !== 0 && locationData.nameAr.length > 0 && !isEdit) {
                        matchArabicName()
                    }
                    // eslint-disable-next-line react-hooks/exhaustive-deps
                }, [locationData.lat, locationData.nameAr])

                return (
                    <Container>
                        <Body>
                            <Form>
                                <Input
                                    disableWithBorder={false}
                                    label="Client Location Name (Arabic)"
                                    name="nameAr"
                                    placeholder="EX: Hyper one"
                                    type="text"
                                    value={locationData.nameAr}
                                    onChange={e => handleLocationDetailsChange(e)}
                                    required
                                    isEditable
                                />
                            </Form>

                            <MapContainer>
                                <GoogleMapComponent
                                    isMarkerShown
                                    containerElement={
                                        <div style={{ height: '100%', width: '100%' }} />
                                    }
                                    setMapLocationData={handleSetMapLocationData}
                                    lat={locationData.lat}
                                    lang={locationData.lang}
                                    isOpen={true}
                                    similarLocations={similarLocations}
                                />
                            </MapContainer>
                        </Body>

                    </Container>
                )
            }

            export default CreateLocation

GoogleMapComponent.js:

      /* eslint-disable eqeqeq */
  import React, { useEffect, useState } from 'react';
  import { compose, withProps } from 'recompose';
  import { withScriptjs, withGoogleMap, GoogleMap, Marker, InfoWindow } from 'react-google-maps';
  import MapMarker from '../../../assets/icons/map-marker.svg'
  import SimilarMarkerIcon from '../../../assets/icons/similar-marker.svg'

  const GoogleMapComponent = compose(
    withProps({
      googleMapURL:
        'https://maps.googleapis.com/maps/api/js?key=AIzaSyC8BSY4LG_gLmgrWTU6HqzxaKhC7hM_uH8&region=EG&language=ar&v=3.exp&libraries=geometry,drawing,places',
      loadingElement: <div style={{ height: `100%` }} />,
      mapElement: <div style={{ height: `100%` }} />,
    }),
    withScriptjs,
    withGoogleMap,
  )(({
    isMarkerShown,
    multipleMarkers,
    similarLocations,
    readOnly
  }) => {


    useEffect(() => {
      console.log(similarLocations, 'Similar locations')
      console.log(similarLocations.length, 'Similar locations length')
    }, [similarLocations])


    const onMarkerDragEnd = (coord) => {
      const { latLng } = coord;
      const lat = latLng.lat();
      const lng = latLng.lng();
      setCurrentPosition({ lat: lat, lang: lng });
      getReverseGeocodingData(lat, lng);
    };

    return (
      <GoogleMap
        defaultZoom={zoom || 12}
        zoom={zoom || 12}
        center={{ lat: currentPosition.lat, lng: currentPosition.lang }}
        onClick={(e) => onMarkerDragEnd(e)}>

        {isMarkerShown && !multipleMarkers && (
          <Marker
            position={{ lat: currentPosition.lat, lng: currentPosition.lang }}
            defaultDraggable={!readOnly}
            onDragEnd={(e) => onMarkerDragEnd(e)}
            options={{
              icon: {
                url: MapMarker,
              },
            }}
          />
        )}
        {
          similarLocations.length > 0 &&
          similarLocations.map(marker => (
            <Marker
              key={marker.location.id}
              position={{ lat: +marker.location.latitude, lng: +marker.location.longitude }}
              onClick={() => {
                handleActiveMarker(marker.location.id)
              }}
              options={{
                icon: {
                  url: SimilarMarkerIcon,
                },
              }}
              visible={similarLocations.includes(marker)}
            >
              {activeMarker === marker.location.id ? (
                <InfoWindow onCloseClick={() => setActiveMarker(null)}>
                  <div>{marker.location.name_ar}</div>
                </InfoWindow>
              ) : null}
            </Marker>
          ))
        }
      </GoogleMap>
    );
  });

  export default GoogleMapComponent;

Check if a JavaScript variable type has keys

I want to pass some data through a for...in loop. I need to check if the data type of data (which is unknown until runtime) makes sense to run through that loop first. All of Array, Object, and String are valid, but if data instanceof String then data[i] is still valid and returns the character in data at position i. I only want to get entire values (i.e. other scalars and objects), not parts of strings. I’m not sure if there are data types other than Array and Object that can contain multiple values and therefore make sense to loop over.

What’s a good test for such an object? This is what I’ve got so far, but I don’t know if it covers all cases.

if (typeof data === "object" && (data instanceof Array || data instanceof Object)) {
  for (let i in data) {
    // ...
  }
}

I’ve also looked at iterable, but Objects aren’t iterable, only Arrays.

Flatten Tree Leaves Typescript (reversed)

I need help dealing with generics.
The function should “pick” leaves and in case of duplicates raise the branch.

const inputSchema = {
    playerResponse: {
        videoDetails: {
            title: 'pick',
            shortDescription: 'pick',
            thumbnail: {
                thumbnails: {
                    '4': {
                        url: 'pick',
                        height: 'pick',
                        width: 'pick',
                    },
                },
            },
        },
    },
    streamingData: {
        formats: {
            0: {
                url: 'pick'
            }
        }
    }
}
type output = {
    videoDetails: {
        title: string,
        shortDescription: string,
    },
    thumbnails: [
        null,
        null,
        null,
        null,
        {
            url: string,
            height: number,
            width: number,
        },
    ],
    formats: [
        {
            url: string,
        },
    ],
}

function flattenSchema<T>(input:T){
    return ...
}

I’ve tried using dot-prop to flatten the structure, but I’m having trouble with the types. Specifically, I’m not sure how to maintain the correct type information after flattening the structure.

for (const path of flattenedPaths) {
    try {
        let value = getProperty(schema, path)
        if (!value) {
            value = undefined // erase unknown values
        }

        const apiValue = getProperty(sourceOfTruth, path)

        const lastPath = path.split('.')?.splice(-2)?.join('.') || ''

        // modify by reference
        setProperty(outputSchema, lastPath, apiValue)
    } catch (error) {}
}
return Ok({ body: outputSchema })

I would appreciate any advice or guidance on how to properly flatten this data structure with generics in TypeScript. Thank you in advance for your help!

Dates given by new Date and new Date from string differ [duplicate]

When I try to initialize a new Date object, being it 1:18AM at my current location, I get
Thu Apr 13 2023 01:18:16 GMT+0100 (GMT+01:00)

I am working with times in ISO Formats, when I create a new Date object and I pass an ISO String to it, such as
2023-04-12T23:18:15.519Z
I get
Thu Apr 13 2023 00:18:15 GMT+0100 (GMT+01:00)

How can this be? I am implemeting a countdown timer in a React project and this is driving me nuts.

I get the same result upon using Luxon. Any ideas?

In Docusaurus v2, is there a way to handle redirects to /default.aspx that Sharepoint automatically inserts into every page?

I have a Docusaurus site hosted under <SHAREPOINT_SITE_URL>/SitePages/dev. The first time I visit the page from outside, I get <SHAREPOINT_URL/default.aspx, a route which Docusaurus doesn’t understand. First page visit

But then as soon as I click any link within the site navigation, Docusaurus starts working perfectly and continues working unless I either:
a. Refresh the page
b. Open a new link to the site from outside

I need to be able to create links to documents in Docusaurus from outside of Docusaurus itself (e.g. via email or in private messages), so I can’t just tell users to rely on the internal navigation after they hit the initial 404 (and it’s just a bad user experience).

I’ve tried using @docusaurus/plugin-client-redirects with toExtensions: ['aspx'] and with fromExtensions: ['aspx'] and neither seem to make an impact.

I’ve tried using createRedirects but I don’t really know what I’m doing and I don’t see a lot of great examples out there using @docusaurus/plugin-client-redirects for something like this.

createRedirects(existingPath) {
  if (existingPath.endsWith('/default.aspx')) {
    return existingPath.replace('/default.aspx', '');
  }
  return undefined; 
},

Parsing array objects in js objects to xml not working

Hey I’m trying to parse a javascript object to xml string in node.js app. I’m using the npm package json2xml like this

json2xml(jsonObject, { header: true });

my issue is that when there’s an array object it will parse it like this:

root: {
    foo: [
        {
            bar: 'a',
        },
        {
            bar: 'b',
        },
    ],
};
<root>
    <foo>
        <bar>a</bar>
        <bar>a</bar>
    </foo>

and not like this:

<root>
    <foo>
        <bar>a</bar>
    </foo>
    <foo>
        <bar>b</bar>
    </foo>
</root>

as I wish it did. Do you have any suggestions or any other libraries I can use to fix this issue?

I’ve tried couple of other libraries: jstoxml, @javadev/xmltojson, fast-xml-parser, that didn’t fix the issue. I’m thinking to write my own jsToXml parser xD

blockchain other nodes are not receiving the mined block

i am taking an online blockchain course and the code runs normal for him but its not on my side ,blockchain nodes are connected with each other when using postman but when i mine a block only one node is receiving the mined block.

i tried running it again, make the algorithm harder to take longer time, changed the ports, made sure that the nodes where connected but nothing worked, i am trying to make an lms system with blockchain as a dataholder, do you recommend to keep doing it and if yes i am little lost and i need help.

here is the code where the problem is


app.get('/mine', function(req,res){
    const lastBlock = blockchain.getLastBlock();
    const previousBlockhash = lastBlock['hash'];
    const currentBlockData = {
        USER: blockchain.pendingUSER,
        index: lastBlock['index'] +1
    };

    const nonce = blockchain.ProofOfWork(previousBlockhash,currentBlockData);
    const blockhash = blockchain.hashBlock(previousBlockhash,currentBlockData,nonce);
    const newblock = blockchain.createBlock(nonce,previousBlockhash,blockhash);
    const request_promises = [];

    blockchain.networkNodes.forEach(networkNodeURL =>{
        const request_Options = {
            uri: networkNodeURL + '/receive-new-block',
            method: 'POST',
            body: {
                newblock:newblock
            },
            json:true
        };

        request_promises.push(request_promise(request_Options));
        
    });
    Promise.all(request_promises)
    .then(data =>{
        res.json({
        note:"new block mined successfully",
        block: newblock
     });
    })
 
});


app.post('/receive-new-block',function(req,res){

    const newblock = req.body.newblock;
    const lastBlock = blockchain.getLastBlock();
    const correct_hash = lastBlock.hash === newblock.previousBlockhash;
    const correct_index = lastBlock['index'] +1 === newblock['index'];

    if(correct_hash && correct_index){
        blockchain.chain.push(newblock);
        res.json({
            note:'new block is added to the chain.',
            newblock:newblock
        });
    }
    else{
        res.json({
            note:'block was rejected',
            newblock:newblock
        })
    }

});

app.post('/USER', function(req,res){
    const newUSER = req.body;
    const blockIndex= blockchain.addUserToPendingUSER(newUSER);
    res.json({note:`USER will be added in block ${blockIndex}.`})
});



app.post('/USER/broadcast',function(req,res){
  

    const newUSER = blockchain.CreateNewUSER(req.body.Academic_id,req.body.Firstname,req.body.Lastname,req.body.birthdate,req.body.academic_year);
    blockchain.addUserToPendingUSER(newUSER);
    const request_promises = [];
    blockchain.networkNodes.forEach(networkNodeURL =>{
        const request_Options = {
            uri: networkNodeURL + '/USER',
            method: 'POST',
            body: newUSER,
            json:true
        };

        request_promises.push(request_promise(request_Options));
    });
    Promise.all(request_promises)
    .then(data=>{
        res.json({note:'user is created and broadcasted to other nodes'})
    });
    
});

even though this function almost works the same it works normal and all nodes do receive the message that is sent to 1 node

Getting page content via XMLHTTPRequest

I am using Protractor for my testing. I have 100 links on a page, rather than clicking on each link and checking the page content I am trying to get the page content via XMLHTTPRequest. I am passing all the contents in the request header that I see on the browser for that page. However, when I run the below code I am getting the log in page, apparently because I do not have active session. However, my UI tests in the browser continues to work fine so I am not logged out on my UI tests.
My questions are:

  1. Is there a way for passing current browser session to the XMLHTTPRequest so that I am not redirected to the log in page?
  2. Is there any other way I can get the page content without having to manually open each of the pages?

Here is my code

            var request = new XMLHttpRequest();
            let cookies = await browser.manage().getCookies();
            let cookie = "";
            for(let obj of cookies){
                cookie+= Object.keys(obj).map(() => obj.name + "=" + obj.value);
            }
            cookie.replaceAll(",", ";")
            request.open('GET', 'https://mybaseURL.com/member/XX001', false);
            request.withCredentials = true;
            request.setRequestHeader("sec-ch-ua", ""Chromium";v="112", "Google Chrome";v="112", "Not:A-Brand";v="99"");
            request.setRequestHeader("sec-ch-ua-mobile", "?0");
            request.setRequestHeader("sec-ch-ua-platform", "Windows");
            request.setRequestHeader("Sec-Fetch-Dest", "empty");
            request.setRequestHeader("Sec-Fetch-Mode", "cors");
            request.setRequestHeader("Sec-Fetch-Site", "same-origin");
            request.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36");
            request.setRequestHeader("Accept", "application/json");
            // request.setRequestHeader("Accept-Encoding", "gzip, deflate, br");
            request.setRequestHeader("Accept-Language", "en-US,en;q=0.9");
            // request.setRequestHeader("Connection", "keep-alive");
            request.setRequestHeader("Content-Type", "application/json");
            request.setRequestHeader("Cookie", cookie);
            request.send(null);
            console.log(request.responseText)

Response:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="https://mybaseurl.com/signon.do?TYPE=123456&amp;REALMOID=06-123456-1234-1234-a702-3a6f0a060000&amp;GUID=&amp;SMAUTHREASON=0&amp;METHOD=GET&amp;SMAGENTNAME=$SM$vO344545Q%245454545543C%2bOm645545en5s3&amp;TARGET=$SM$https%3a%2f%2fmybaseurl%2ecom%2fmember%2fXX001">here</a>.</p>
</body></html>

fontFamily renders on ckeditor5 but not fontSize

When I import Font and add ‘fontFamily’ to the toolbar, it appears. But when I add ‘fontSize’ (which should also be from Font), it does not appear in the toolbar

import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote.js';
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor.js';
import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials.js';
import Font from '@ckeditor/ckeditor5-font/src/font';
import Heading from '@ckeditor/ckeditor5-heading/src/heading.js';
import IndentBlock from '@ckeditor/ckeditor5-indent/src/indentblock.js';
import List from '@ckeditor/ckeditor5-list/src/documentlist.js';
import ListProperties from '@ckeditor/ckeditor5-list/src/documentlistproperties.js';
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph.js';
import Table from '@ckeditor/ckeditor5-table/src/table.js';
import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar.js';

class Editor extends ClassicEditor {}

Editor.builtinPlugins = [
  Essentials,
  Heading,
  IndentBlock,
  List,
  ListProperties,
  Paragraph,
  Table,
  TableToolbar,
  Font,
];

Editor.defaultConfig = {
  toolbar: {
    items: [
      'bulletedList',
      'numberedList',
      '|',
      'outdent',
      '|',
      'insertTable',
      'fontFamily',
      'fontSize',
    ],
  },
  language: 'en',
  table: {
    contentToolbar: ['tableColumn', 'tableRow', 'mergeTableCells'],
  },
  licenseKey: '',
};

export default Editor;

And in my package.JSON I added: “@ckeditor/ckeditor5-font”: “^34.1.0”. All others are also 34.1.0

I thought if fontFamily worked, fontSize would too, but I am not sure why it is not. Any advice would be appreciated!

enter image description here

Jquery get table data that matches div ID

I am trying to use jquery each function on a table to get data from an html table which is inside a div with it’s own id on another button click and match the id with an input value. For example from my structure below, the div with id 329 has it own table and it’s matches the input value of 329. Since it matches the input value, I want to loop through that specific table and get the td values inside that particular div.
My parent div with the tables looks like this.

$("#btn").click(function() {
  $(".parentDIV").each(function(i, el2) {

    var sechID = el2.id;
    var tables = el2.innerHTML // -- -- > I can see each table with the div id here.
    ('.table tbody tr').each(function() {
      var numbers = $(this).find('td').eq(0);
    });
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="fname" name="fname" value="329"><br><br>
<div class="parentDIV">
  <div class="container" id="378">

    <h2 class="myclass Pointer" id="329">
      <span class="glyphicon glyphicon-plus"></span>
      <span>Employee Email</span>
    </h2>
    <div class="container" id="329" style="display: none;">

      <table class="table table-striped">
        <thead>...
        </thead>
        <tbody>..... </tbody>

      </table>
    </div>


    <div class="container" id="9378">
      <h2 class="myclass Pointer" id="1329">
        <span class="glyphicon glyphicon-plus"></span>
        <span>Employee</span>
      </h2>
      <div class="container" id="1329" style="display: none;">

        <table class="table table-striped">
          <thead>...
          </thead>
          <tbody>..... </tbody>

        </table>
      </div>


      <div class="container" id="878">
        <h2 class="myclass Pointer" id="2329">
          <span class="glyphicon glyphicon-plus"></span>
          <span>Employee</span>
        </h2>
        <div class="container" id="2329" style="display: none;">

          <table class="table table-striped">
            <thead>...
            </thead>
            <tbody>..... </tbody>

          </table>
        </div>
      </div>

Chrome Extension – Making HTTP requests and updating page content continuously

I’m trying to code a Chrome extension where when a user Googles something, every result/site that comes up is sent to an API which then returns data I want to display next to the corresponding site’s name.

I know I can make HTTP requests with XMLHttpRequest, but I’m not sure how or even if this would work asynchronously.

What I mean is the requests should not be blocking/make the page load slower, but I also need to update the page’s content as the responses come in. The page should update as the HTTP responses come in, not wait for them all to come in and then update.

Is this possible? If so, could someone point me in the right direction.

Thanks!

Filter function don’t return proper amount of elements

I have mockedData like below:

export const MOCKED_TRANSACTION_HISTORY = [
  {
    id: 1,
    transactionDate: '01 / 03 / 2023',
    transactionType: 'payment',
    transactionValue: 1000,
    currency: 'PLN',
  },
  {
    id: 2,
    transactionDate: '01 / 01 / 2023',
    transactionType: 'withrawal',
    transactionValue: 50,
    currency: 'PLN',
  },
  {
    id: 3,
    transactionDate: '03 / 04 / 2023',
    transactionType: 'withrawal',
    transactionValue: 50,
    currency: 'PLN',
  },
  {
    id: 4,
    transactionDate: '01 / 04 / 2023',
    transactionType: 'withrawal',
    transactionValue: 50,
    currency: 'PLN',
  },
  {
    id: 5,
    transactionDate: '02 / 04 / 2023',
    transactionType: 'payment',
    transactionValue: 510,
    currency: 'EUR',
  },
  {
    id: 6,
    transactionDate: '01 / 10 / 2021',
    transactionType: 'payment',
    transactionValue: 150,
    currency: 'EUR',
  },
  {
    id: 7,
    transactionDate: '01 / 01 / 2019',
    transactionType: 'withrawal',
    transactionValue: 510,
    currency: 'EUR',
  },
];

My aim is to filter from mockedData elements which transactionDate is between provided startDate and endDate passed as params in useParams from react-router-dom.
Below is the output from the console, both are typeof strings

startDate: 01.03.2023;
endDate: 30.04.2023

then I change startDate and endDate to be typeof object and I create fromDate and toDate variables.

  const startDateParts = startDate.split('.');
      const startDateAsDate = new Date(
        Number(startDateParts[2]),
        Number(startDateParts[1]) - 1,
        Number(startDateParts[0]),
      );
      const endDateParts = endDate.split('.');
      const endDateAsDate = new Date(
        Number(endDateParts[2]),
        Number(endDateParts[1]) - 1,
        Number(endDateParts[0]),
      );

      const fromDate = Math.min(startDateAsDate.getTime(), endDateAsDate.getTime());
      const toDate = Math.max(startDateAsDate.getTime(), endDateAsDate.getTime());

For provided startDate and endDate those are fromDate and toDate:
from 1677625200000;
to 1682805600000

Can You please let me know why with below code comparison variable returns just an element with id:3 from mockedData

const [filteredData, setFilteredData] = useState<any | undefined>([]);
const data = MOCKED_TRANSACTION_HISTORY;

const comparison = data.filter((singleTransaction) => {
            const date = new Date(singleTransaction.transactionDate);
            console.log('transaction', date.getTime());
            return date.getTime() <= toDate && date.getTime() >= fromDate;
          });
setFilteredData(comparison);
console.log('comp:', comparison);

Although as You can see in mockedData there should be 4 elements ?

thanks

When I press the button, picture doesnt show up

im making a simple application that has 4 buttons that supposed to display pictures if flowers. But when I press the first button nothing happenes and this error pops up lowerPics%C3%B075__30056__32169.1663778062.1280.1280.webp:1 GET http://127.0.0.1:5500/Chapter%201/lowerPics%C3%B075__30056__32169.1663778062.1280.1280.webp 404 (Not Found)

I have no idea what this is, google either.

let dendelionSrc =
  "flowerPics36075__30056__32169.1663778062.1280.1280.webp";
let rose = "flowerPicssingle-red-rose.jpg";
let tulip = "flowerPicstulip-types-for-spring-garden-1315804-hero- 
5 c10c927e00c459eb24c702be447e50d.jpg ";
let mayflower = "flowerPicsMayflowerTrailingArbutus.webp";
img {
  display: block;
}

button {
  margin-top: 10px;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Flower Pictures</title>
</head>

<body>
  <div>
    <img id='picture' width="250" height="250" src="#">

    <button id='dendelion' class="btn" onclick="document.getElementById('picture').src =  
                   dendelionSrc">Dendelion</button> //ERROR HERE

    <button id="rose">Rose</button>

    <button id="tulip">Tulip</button>

    <button id="mayflower">Mayflower</button>

  </div>


</body>

</html>

Change the color of an element on mouseenter

i want to make the nav color change every time there’s a mouseenter until it reaches 4 different colors. So far im able to change only the background color of the first nav element, even when usingvquerySelectorAll().

This is the CSS
nav {
z-index: 1;
position: fixed;
width: 52px;
height: 299px;
font-family: 'News Cycle';
font-style: bold;
font-weight:600;
font-size: 20px;
line-height: 33px;
text-align: center;

color: #000000;

}

nav li {
    list-style: none;
    padding-top: 30px;
    padding-right: 10px;
    
}

nav a {
    color: rgba(5, 5, 5);
    text-decoration: none;
}


and this is the javascript i have



const colors = ['red', 'green', 'blue', 'yellow'];
let currentIndex = 0;
const myElement = document.getElementById('info');

myElement.addEventListener('mouseenter', () => {
  myElement.style.color = colors[currentIndex];
  currentIndex = (currentIndex + 1) % colors.length;
});

I want the code to select the text color of ALL the nav elements but only works for backgroundColor for the first nav, if that makes sense