Ramda JS – Pass optional argument to the second function of a pipe

I am trying to refactor this code:

async function getUserDataByUsername(username, cached = true) {
  const usernameRef = firestore
    .collection("usernames")
    .doc(username.toLowerCase());

  const usernameDoc = await usernameRef.get();

  if (!usernameDoc.exists) {
    throw userErrors.userNotFound();
  }

  const { userId } = usernameDoc.data();

  return memoizedGetUserData(userId, cached);
}

For that, I have thought to split it in smaller parts, as follows:

function memoizedGetUserData(userId, cached = true) { 
  ... Fetching from LRU or DB ... 
}

async function getUserId(username) {
  const usernameRef = firestore
    .collection("usernames")
    .doc(username.toLowerCase());

  const usernameDoc = await usernameRef.get();

  if (!usernameDoc.exists) {
    throw userErrors.userNotFound();
  }

  const { userId } = usernameDoc.data();

  return userId;
}

async function getUserDataByUsername(username, cached = true) {
  const userId = await getUserId(username);

  return memoizedGetUserData(userId, cached);
}

Now, I want to apply Ramda to this module. I have never used this library before, but I have read that it is really cool, and makes the code easier to understand with some of it utilities.

What I am trying is to refactor the original method using the pipeline style, as follows:

import R from "ramda";

...

const getUserDataByUsername = R.pipeP(getUserId, memoizedGetUserData);

But… how can I pass the second optional parameter “cached”, only to the second argument of my pipe??

How to split object into multiple objects by props names in JS

I am trying to split object into multiple objects. Here is how it looks. It is actually array of objects.

[
  {
    interval_9_gun_time_milliseconds: 0,
    interval_9_net_time_milliseconds: 0,
    interval_9_gun_pace: '00:07:04',
    interval_8_gun_time_milliseconds: 0,
    interval_8_net_time_milliseconds: 0,
    interval_8_gun_pace: '00:07:04',
    entry_id: 200
  },
  {
    interval_9_gun_time_milliseconds: 0,
    interval_9_net_time_milliseconds: 0,
    interval_9_gun_pace: '00:02:04',
    interval_8_gun_time_milliseconds: 0,
    interval_8_net_time_milliseconds: 0,
    interval_8_gun_pace: '00:04:04',
    entry_id: 404
  },
  {
     entry_id: 1
  }
]

So expected result should be:

 [
      {
        interval_9_gun_time_milliseconds: 0,
        interval_9_net_time_milliseconds: 0,
        interval_9_gun_pace: '00:07:04',
        entry_id: 200
      },
      {
        interval_8_gun_time_milliseconds: 0,
        interval_8_net_time_milliseconds: 0,
        interval_8_gun_pace: '00:07:04',
        entry_id: 200
      },
      {
        interval_9_gun_time_milliseconds: 0,
        interval_9_net_time_milliseconds: 0,
        interval_9_gun_pace: '00:02:04',
        entry_id: 404
      },
      {
        interval_8_gun_time_milliseconds: 0,
        interval_8_net_time_milliseconds: 0,
        interval_8_gun_pace: '00:04:04',
        entry_id: 404
      }
    ]

Bottom line split and group object by interval_{number} and add other props, if object doesn’t have interval remove it.

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?