addeventListener not working on all elements

Hello I mam facing a problem with my script.

I am beginner in JS and I am trying to add event listener to buttons generated by a foreach but only the last button generated is responding to the addeventlistener.

I am also facing a pb of variable range with the getLocation(flight) function which is returning undefined outside the fuction while the console.log in the function is displaying the good variable value.

Can someone help?



let resultatAPIMeteo;

let long;
let lat;
let buttonId;

const URL = "https://opensky-network.org/api/states/all?lamin=45.8389&lomin=5.9962&lamax=47.8229&lomax=10.5226";
const TITREMETEO = document.querySelector('.titre-meteo');
const IMG = document.querySelector('.bloc-logo');
const temps = document.querySelector('.temps');
const temperature = document.querySelector('.temperature');
const localisation = document.querySelector('.localisation');
const tbody = document.querySelector(('#body'));

let flights = [];
let table = document.getElementById("tableau");

AppelAPI();

function AppelAPI() {
    fetch(URL)
        .then((response) => {
            return response.json()
        })
        .then((data) => {
            let i = 0;

            getFlights(data);
            console.log(data)
            console.log(flights)

            flights.forEach(flight => {
                let i = flights.indexOf(flight)
                console.log(flight);
                long = flight[5];
                lat = flight[6];

                let city = getLocation(flight);
                console.log("city: " + city);

                let meteoDepart = "test";
                let meteoArrivee = "test";

                /* let newRow = document.createElement('tr');
                let newFlightNumber = document.createElement('td');
                let newflightNumberText = flight[1];
                let newProvenance = document.createElement('td');
                let newProvenanceText = flight[2];
                let newCity = document.createElement('td');
                let newCityText = city;


                tbody.append(newRow);

                newFlightNumber.textContent = newflightNumberText;
                newRow.append(newFlightNumber);

                newProvenance.textContent = newProvenanceText;
                newRow.append(newProvenance);

                newCity.textContent = newCityText;
                newRow.append(newCity); */
                

                if(i % 2 === 0) {
                    table.innerHTML += `<tr class='pair'>n` +
                        "    <td>" + flight[1] + "</td>n" +
                        "    <td>" + flight[2] + "</td>n" +
                        `    <td>${city}</td>n` +
                        `    <td><button id="tr-${i}"  onclick="alert('Bouton cliqué')">Météo</button></td>`+
                        "</tr>n";
                } else {
                    table.innerHTML += `<tr class='pair'>n` +
                        "    <td>" + flight[1] + "</td>n" +
                        "    <td>" + flight[2] + "</td>n" +
                        `    <td>${city}</td>n` +
                        `    <td><button id="tr-${i}"  onclick="alert('Bouton cliqué')">Météo</button></td>`+
                        "</tr>n";
                }
                console.log('tr-'+i);
                let button = document.getElementById('tr-'+i);
                tbody.style.color='white';
                button.style.backgroundColor='orange';

                button.addEventListener('click', (e) => {
                    console.log('from api: click');
                    AppelApiMeteo(flight);
                });
                i++;
            })
        })
}

function AppelApiMeteo(flight) {
    console.log('from apimeteo: click');

    let lattitude = flight[6];
    let longitude = flight[5];
    let URLMeteo = `https://api.openweathermap.org/data/2.5/onecall?lat=${lattitude}&lon=${longitude}&exclude=minutely&units=metric&lang=fr&appid=${CLEAPIMETEO}`;
    console.log(URLMeteo);
    fetch(URLMeteo)
        .then((response) => {
            return response.json();
        })
        .then((data) => {
            resultatAPIMeteo = data;

            TITREMETEO.innerHTML = `Météo du vol ${flight[1]} en provenance de ${flight[2]}`;
            IMG.innerHTML = `<img src="./ressources/jour/${resultatAPIMeteo.current.weather[0].icon}.svg" alt="logo du temps qu'il fait" className="logo-meteo">`;
            temps.innerText = resultatAPIMeteo.current.weather[0].description;
            temperature.innerText = `${Math.trunc(resultatAPIMeteo.current.temp)}°`;
            localisation.innerText = resultatAPIMeteo.timezone;

            console.log('meteo data:' + resultatAPIMeteo.current.weather[0].description);
        })
}

function getFlights(data) {
    console.log(data.states);
    data.states.forEach(element =>{
        flights.push(element)
    })
}

function getLocation(flight){
    let lattitude = flight[6];
    let longitude = flight[5];
    let geocoder;
    geocoder = new google.maps.Geocoder();
    let latlng = {
        lat: parseFloat(lattitude),
        lng: parseFloat(longitude),
    };

    geocoder
        .geocode({location: latlng})
        .then((response) => {
            console.log("pos: " + response.results[7].address_components[0].long_name);
            return response.results[7].address_components[0].long_name;
        })
        .catch((e) => window.alert("Geocoder failed due to: " + e));
}
/*
let row = document.createElement('tr')
let columnNum = document.createElement('th');
let columnLat = document.createElement('th');
let columnLong = document.createElement('th');
let columnMeteo = document.createElement('th')

for(let i = 0; i < data.length; i++) {

    columnNum.textContent = resultatsAPI[i].icao24;

    table.appendChild(row);
    row.appendChild(columnNum);
    row.appendChild(columnLat);
    row.appendChild(columnLong);
    row.appendChild(columnMeteo);


    console.log('test:' + resultatsAPI[i].icao24);
}
*/

custom columns selection google script

I’m using a google script to save a google sheet as a csv daily, I would like to only save desired columns (in this case columns 1,2,4,9,14,25,26 and 44).
I tried to modify the range, an if after columns loop, putting only the wanted columns as i value for columns loop… but the script still saves the whole google sheet. Any ideas ? Thanks

/*Sauvegarde de Stylez*/ 

function saveAsCSV_Stylez() {
  // Prompts the user for the file name
  var fileName = "CSV_Stylez"; //Browser.inputBox("Save CSV file as (e.g. myCSVFile):");
  // Add the ".csv" extension to the file name
  fileName = fileName + ".csv";
  delteFile_Stylez(fileName);
  // Convert the range data to CSV format
  var csvFile = convertRangeToCsvFile_Stylez(fileName);
  // Create a file in Drive with the given name, the CSV data and MimeType (file type)
  //DriveApp.createFile(fileName, csvFile, MimeType.CSV);
  var CF = DriveApp.getFolderById('1D5NBqNRb7tdpfiiUyPM18cfMnPzhZHVl').createFile(fileName, csvFile, MimeType.CSV);
}
 
function convertRangeToCsvFile_Stylez(csvFileName) {
  // Get the selected range in the spreadsheet
  var spreadsheet = SpreadsheetApp.getActive();
  spreadsheet.getRange('A1').activate();
  spreadsheet.setActiveSheet(spreadsheet.getSheetByName('CSV_Stylez'), true);
  spreadsheet.getRange('A1:AR3500').activate();
  var ws = SpreadsheetApp.getActiveSpreadsheet().getActiveSelection();
  try {
    var data = ws.getValues();
    var csvFile = undefined; 
    // Loop through the data in the range and build a string with the CSV data
    if (data.length > 1) {
      var csv = "";
      for (var row = 0; row < data.length; row++) {
        for (var col = 0; col < data[row].length; col++) {
          if (data[row][col].toString().indexOf(",") != -1) {
            data[row][col] = """ + data[row][col] + """;
          }
        }
 
        // Join each row's columns
        // Add a carriage return to end of each row, except for the last one
        if (row < data.length-1) {
          csv += data[row].join(",") + "rn";
        }
        else {
          csv += data[row];
        }
      }
      csvFile = csv;
    }
    return csvFile;
  }
  catch(err) {
    Logger.log(err);
  }
}


function delteFile_Stylez(myFileName) {
  var allFiles = DriveApp.getFolderById('1D5NBqNRb7tdpfiiUyPM18cfMnPzhZHVl').getFilesByName(myFileName);
  while (allFiles.hasNext()) {
    var thisFile = allFiles.next();
    thisFile.setTrashed(true);
  };
  function convertRangeToCsvFileCSV_LAD(csvFileName) {
  // Get the selected range in the spreadsheet
  var spreadsheet = SpreadsheetApp.getActive();
  spreadsheet.getRange('A1').activate();
  spreadsheet.setActiveSheet(spreadsheet.getSheetByName('CSV_Stylez'), true);
  spreadsheet.getRange('A1:AR3500').activate();
  var ws = SpreadsheetApp.getActiveSpreadsheet().getActiveSelection();
  try {
    var data = ws.getValues();
    var csvFile = undefined; 
    // Loop through the data in the range and build a string with the CSV data
    if (data.length > 1) {
      var csv = "";
      for (var row = 0; row < data.length; row++) {
        for (var col = 0; col < data[row].length; col++) {
          if (data[row][col].toString().indexOf(",") != -1) {
            data[row][col] = """ + data[row][col] + """;
          }
        }
         
        // Join each row's columns
        // Add a carriage return to end of each row, except for the last one
        if (row < data.length-1) {
          csv += data[row].join(",") + "rn";
        }
        else {
          csv += data[row];
        }
      }
      csvFile = csv;
    }
    return csvFile;
  }
  catch(err) {
    Logger.log(err);
  }
}
};

How to adjust the space between heading, legend and plot area on Plotly?

How can I adjust space between heading, legend and plot area in Plotly? In particularly I need to increase the space between them without one another collide. I’ve attached the current output screenshot and my code snippet as following.

[Current Output of the chart

 <Plot
        data={dataArray}
        layout={{
          barmode: "stack",
          autosize: true,
          title: preHeading + mainTitle,
          margin: {
            t: 135,
            autoexpand: true,
          },
          xaxis: {
            // all "layout.xaxis" attributes: #layout-xaxis
            title: xTitle, // more about "layout.xaxis.title": #layout-xaxis-title
            // dtick: 1,
          },
          yaxis: {
            // all "layout.xaxis" attributes: #layout-xaxis
            title: yTitle, // more about "layout.xaxis.title": #layout-xaxis-title
          },
          font: {
            // family: "Courier New, monospace",
            size: 12,
            color: "#7f7f7f",
          },
          legend: {
            bgcolor: "yellow",
            x: 0,
            y: 1.2,
            xanchor: "auto",
            traceorder: "normal",
            orientation: "h",
          },
          marker: { size: 40 },
        }}
        useResizeHandler
        style={{ width: "100%", height: "100%" }}
      />

]1

NodeJS Streams: Readable.pipe() doesn’t send data immediately

From what I understood about streams, Stream.Readable.pipe() should pipe the data as soon as it receives it.

I am trying to implement my own streams but the output is not as expected.

const { Writable, Readable } = require("stream");

const writable = new Writable();
writable.data = [];
writable._write = (chunk, encoding, next) => {
  writable.data.push(chunk.toString());
  console.log(chunk.toString());
  next();
};

const readable = new Readable({
  read() {},
});

readable.pipe(writable);
readable.push("hi");
writable.write("ho");
writable.write("ho");
console.log(writable.data);

The output of this code is

ho
ho
[ 'ho', 'ho' ]
hi

The pipe is writing to the stream later. What does this mean?

Trying to implement a basic search engine by hiding elements that aren’t results, but my code hides everything instead

I am trying to implement a very basic search engine. I iterate through an array of objects, checking if my search term matches some attributes, and if it does, I push each matching object onto an array. Now, in the rest of my code I have it so each object is represented by an element, and each element has a checkbox. Each checkbox has an ID that matches its object’s ID. So…. when I run the search function, I take the matches, correspond them to a checkbox through the IDs, and then I want to hide the elements that don’t match.

The problem is: it hides ALL the elements, instead of just the non-matchings IDs. Furthermore, it works when I want to manipulate the matches (say, surround them in a white border). Thank you for your time I look forward to your input.

Blake

function search() {
     var results = [];
     userData.forEach(task => {
         if (task.value.toLowerCase().includes(searchBar.value.toLowerCase()) 
             || task.note.toLowerCase().includes(searchBar.value.toLowerCase())) {
                 results.push(task.id);
             }
         })

         const checkboxes = document.querySelectorAll(".checkbox");

         checkboxes.forEach(checkbox => {
              if (!results.includes(checkbox.id)) {
                   checkbox.parentElement.style.display = "none";
              }
          })
     }
}

How to pass data between users and different browsers in React?

I am learning React and I’m making an app to better learn.
I created an app with Nodejs backend, Postgres DB and React frontend. I have different users and this is the case of what I need to do:

USER 1: Logs in mozilla and clicks a button on a page.
USER 2: Logs in firefox and sees a new button has appeared, because user in mozilla clicked it. Now he clicks this new button.
USER 1: Because USER 2 clicked new button, USER 1 sees something new displayed.

I am running it locally.

Do something when Promise outside then finished

Here is the code.

function getPromise():Promise<any> {
    let p = new Promise<any>((resolve, reject) => {
        //some logical
        resolve(data);
    });
    p.finally(()=>{ 
        //I want do something when outside then finished! 
        console.log("finally hit");
    });
    return p;
}

function doPromise():void {
    getPromise().then(data => { console.log("then hit"); });
}

But the finally runs before then. So how can I do something after outside then.

I do not want to add finally after then, because the promise called many places. so I want do it in one place.

child route not working in single spa react app

I have created react app using single spa and in my navigation bar React app i am showing which will take me to route page (‘localhost;9000/react’). I need to see how child route will work, I have created child route but if i clicked on childroute my main url isnt working it should show localhost;9000/react/childroute but it was not showing. Below is the code.

//root.component.js

import React from 'react';
import {BrowserRouter as Router, Route, Switch, Link } from "react-router-dom";
import TestRoute from './TestRoute';
//import Reactapp from './Reactapp';
import ReactComponent from './ReactComponent';

export default function Root(props) {
  return (
    <Router baseName='/react'>
       <Switch>
          <Route path="/" component={ReactComponent} />  
          <Route path="/childroute" component={TestRoute} />  
       </Switch>
    </Router>
    
  )
}
//ReactComponent.js
import React from 'react';
import { Link } from 'react-router-dom';

const ReactComponent = () => {
    return(
        <div>
            ReactComponent
            <Link to='/childroute'>Child Route</Link>
        </div>
    )
}
export default ReactComponent;
//TestRoute.js

import React from 'react';

const TestRoute = () => {
    return(
        <div>
            TestPage
        </div>
    )
}
export default TestRoute;
//mf-demo-react.js

import React from "react";
import ReactDOM from "react-dom";
import singleSpaReact from "single-spa-react";
import Root from "./root.component";


const lifecycles = singleSpaReact({
  React,
  ReactDOM,
  rootComponent: Root,
  errorBoundary(err, info, props) {
    // Customize the root error boundary for your microfrontend here.
    return null;
  },
});

export const { bootstrap, mount, unmount } = lifecycles;

React hooks onClick icon change is not working

I want to change my icon onClick. But for some that is not working. What I have done is that, if there is submenuIcon1, it will be rendered. If someone clicks on the submenu option, it will render the submenuIcon2, based on the clicked variable.
Maybe I have done something wrong in the ternary operations. Please can someone help me regarding this?
Required Behavior
Whenever clicking on the submenu options, the icon will change. In this case it will be from submenuIcon1 to submenuIcon2.
Current Behavior
Clicking on the submenu options, the icon doesn’t change.
What I have done so far is that,

const SidebarTitle = () => {
  return (
    <>
      <Box
        width='200px'
        height='160px'
        textAlign='start'
        bgColor='#473198'
        px={5}
        borderRadius={2}
      >
        <Text fontSize='2xl' color='white' fontFamily='Fjord One'>
         Some title
        </Text>
      </Box>
    </>
  );
};

export default function Sidebar() {
  const [selectedSubMenu, setSelectedSubMenu] = useState("");
  const [clicked, setClicked] = useState(false);
  let location = useLocation();

  const handleClick = (title) => {
    setClicked(!clicked);
    if (title === selectedSubMenu) {
      setSelectedSubMenu("");
    } else {
      setSelectedSubMenu(title);
    }
  };

  return (
    <div>
      <Box
        display='flex'
        justifyContent='flex-start'
        alignItems='flex-start'
        mb={10}
      >
        <Box>
          <SidebarTitle />
          {sidebarItems.map((items) => {
            return (
              <Box
                width='200px'
                textAlign='start'
                cursor='pointer'
                onClick={() => {
                  handleClick(items.title);
                  
                }}
                fontFamily='Fjord One'
                boxShadow='lg'
                _hover={{
                  bgColor: "#1a2963",
                  color: "white",
                }}
                key={items.title}
              >
                <Link
                  to={items.url}
                  as={RouterLink}
                  width='100%'
                  _focus={{
                    boxShadow: "none",
                  }}
                  style={{ textDecoration: "none" }}
                >
                  <Box display='flex' justifyContent='space-between'>
                    <Text fontSize='xl' alignItems='flex-start'>
                      {items.title}
                    </Text>
                    {!!items.submenuIcon1 ? (
                      <Box alignItems='flex-start'>{items.submenuIcon1}</Box>
                    ) : clicked ? (
                      <Box alignItems='flex-start'>{items.submenuIcon2}</Box>
                    ) : (
                      <Box></Box>
                    )}
                  </Box>
                </Link>

                <Collapse
                  in={items.title === selectedSubMenu}
                  transition={{ enter: { delay: 0.1 }, exit: { delay: 0.1 } }}
                >
                  {items.subMenu?.map((item) => {
                    return (
                      <Box
                        bgColor='#e4e8e5'
                        boxShadow='md'
                        textAlign='start'
                        width='200px'
                        color='black'
                        _hover={{
                          bgColor: "#666666",
                          color: "white",
                        }}
                        key={item.title}
                        onClick={(event) => {
                          event.stopPropagation();
                        }}
                      >
                        <Link
                          to={item.url}
                          as={RouterLink}
                          width='100%'
                          _focus={{
                            boxShadow: "none",
                          }}
                          style={{ textDecoration: "none" }}
                        >
                          <Text fontFamily='Fjord One'>{item.title} </Text>
                        </Link>
                      </Box>
                    );
                  })}
                </Collapse>
              </Box>
            );
          })}
        </Box>

        <Box width='100%'>
          <TransitionGroup>
            <CSSTransition
              key={location.pathname}
              classNames='fade'
              timeout={300}
            >
              <Routes location={location.pathname}>
              //routes
              </Routes>
            </CSSTransition>
          </TransitionGroup>
        </Box>
      </Box>
    </div>
  );
}

How can i protect api from client?

I’m developing a site with react and nextjs. So in the API folder, I write some API endpoints. Now I don’t know how can I protect them from clients?
I want to use these APIs directly from the site. and I won’t the user be able to access API from his browser.
With jwt can I solve this problem? Or right solution is something else?

Insert slide number and total count between navigation arrows of owl carousel

I have an ngx owl carousel in my angular application with configurations as below:

const carouselOptions = {
 items: 1,
 dots: false,
 nav: true,
 navText: ["<div class='nav-btn prev-slide'></div>","<div class='nav-btn next-slide'></div>"]
};

<owl-carousel [options]="carouselOptions" [carouselClasses]="['owl-theme','row','sliding']">
 <div class="item" *ngFor="let imgUrl of imageList; let i=index">
     <img src={{imgUrl}} alt="image slide" />
 </div>
</owl-carousel>

I have altered the default navigation arrows into custom arrows by using the navText key inside the owl carousel options. What I need is a way to inject the slide numbers as (current slide)/(total slide count) in between this navText arrows of owl carousel.

I tried to check the documentation but they dont have the option to add the step numbers as 1/7 between the navigation arrows.
I have implemented it in a angular application and would like to know a suitable solution to achieve using typescript?

Integrating node modules and JavaScript into our Web API controller calls

Our main backend server is a .net 5 web api project. I’m needing to integrate some javascript modules and javascript code into our functionality. I’m wanting to save on the time of rewriting these modules all into c# to access from our code. Is there any packages or methods to accomplish this or am I best of running a separate node server for this functionality?

webpack: transpile web workers in public folder

I’m next js for my project and it uses webpack 5 to compile typescript codes

I have several web worker scripts inside my public folder under path “/workers/**/*.worker.js”

I was wondering if I can write them in typescript too
or at least use babel to transpile them for es5 (for old browsers)

I know that anything under the “public” folder is served as is and as a file (like a CDN)

can I add a “workers” folder to my project and load them in the public path with webpack and next js?

How to bind react route to a shown dialog?

React Router has a good tutorial on Nested Routes.

And it’s pretty easy to create and understand.

However, I want to bind a route to a dialog.

Basically I have a list of customers at /customers and I have a New button on it. When it’s clicked a form is shown inside a dialog. I’m using Material UI. I want to change the route to /customers/create route and as the result of that route change show the dialog. This means that even if users hit F5 and refresh the page, they would still see the form shown in the dialog.

I can’t make it work. I created the nested <Route /> definition:

<Routes>
    <Route path='/customers' element={<Customers />}>
        <Route path='create' element={<CreateCustomer />} />
    </Route>
</Routes>

And I also inserted an <Outlet /> in my Customers.js:

import { Outlet } from 'react-router-dom'

const Customers = () => {
    const [dialogIsShown, setDialogIsShown] = useState(false);
    return <div>
        <Button onClick={() => setDialogIsShown(true)}>Create</Button>
        {* customer creation component is here, inside a dialog *}
        <Dilog open={dialogIsShown}>
            <CreateCustomer />
        </Dialog>
        {* other UI parts *}
        <Outlet />
    </div>
}

And when I click the new button, I use useNavigate to change route. But nothing happens.

I’m stuck here.

Any help is appreciated.

Updating a global variable from within a function

I am defining two variables:

var information;
var secondary_information;

I update these variables within my function:

async function fetchInfo() {
var num = Math.floor(Math.random() * 20 + 1);

const url = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${pos.current.coords.latitude},${pos.current.coords.longitude}&radius=12000&type=restaurant&key=${key}`;

await fetch(url)
  .then((response) => response.json())
  .then((data) => setSearchResponse(data))
  .then(console.log("api request fired."));

let place_id = searchResponse.results[num].place_id;


const secondary_url = `https://maps.googleapis.com/maps/api/place/details/json?fields=formatted_phone_number,opening_hours,formatted_address&place_id=${place_id}&key=${key}`;

await fetch(secondary_url)
  .then((response) => response.json())
  .then((data) => setsecondarySearchResponse(data))
  .then(console.log("secondary api request fired."));

 information = {
  name: searchResponse.results[num].name,
  open_now: searchResponse.results[num].opening_hours.open_now,
  rating: searchResponse.results[num].rating,
  price: searchResponse.results[num].price_level
};

 secondary_information = {
  phone_number: secondarySearchResponse.result.formatted_phone_number,
  daily_hours: secondarySearchResponse.result.opening_hours.weekday_text,
  address: secondarySearchResponse.result.formatted_address
};
}

When I console log the variables from within the function it works as intended.

I am trying to pass the variables down as props to a react component but it keeps passing an empty object instead:

return (
<div className="App">
  <Filters />
  <Button variant="primary" onClick={fetchInfo}>
    Randomizer
  </Button>{" "}
  <Result info={information} />
</div>
);

Additionally, I have no clue if this is the correct way I should be going about making these API calls and storing them into state but this is the way that made sense to me. Any feedback is greatly appreciated.