Error “updates.map is not a function” when modifying cells of tables retrieved from BigQuery via an API

Here’s the revised version of your question with the HTML structure and server details included:


Title:
Error “updates.map is not a function” when modifying cells of tables retrieved from BigQuery via an API

Body:

I’m developing a web application that allows editing and saving data to a BigQuery database through a REST API. Data is fetched from multiple tables in BigQuery, and users can modify specific cells in a web interface. These modified data are then sent back to the server to update BigQuery.

Workflow:

  1. Initial Query:

    • Data is queried from BigQuery using a custom API. This query retrieves data from multiple tables and displays it in an HTML table on the frontend.
    • Example of SQL query used:
      SELECT * FROM `project-database.table` WHERE ...
      
  2. HTML Structure:
    The data is displayed in a table where users can edit specific cells:

    <table id="data-table">
        <thead>
            <tr>
                <th>SITIO</th>
                <th>SMP</th>
                <th>proyecto_alcance</th>
                <!-- Other columns -->
            </tr>
        </thead>
        <tbody>
            <tr>
                <td contenteditable="true" data-column="SITIO">ANT.Santuario-2</td>
                <td contenteditable="true" data-column="SMP">SMP-WO-0131959</td>
                <td contenteditable="true" data-column="proyecto_alcance">LTE1900</td>
                <!-- Other columns -->
                <td><button class="edit-btn">Editar</button><button class="save-btn" style="display:none;">Guardar</button></td>
            </tr>
        </tbody>
    </table>
    
  3. Frontend Editing:

    • Users can edit specific cells in the HTML table. When an edit is made, I capture the modified data and compare it with the original data to send only the changes to the server.
  4. Sending Modified Data:

    • The frontend code filters the data to send only the cells that have been modified. Here is the relevant code:
      async function saveDataToBigQuery(data) {
          const updates = {};
      
          for (const key in data) {
              if (data[key] !== originalData[key] && data[key]) {
                  updates[key] = data[key];
              }
          }
      
          if (Object.keys(updates).length === 0) {
              console.log('No changes found to send to the server.');
              return;
          }
      
          try {
              const response = await fetch('https://example.com/api/edit', {
                  method: 'PUT',
                  headers: {
                      'Content-Type': 'application/json',
                  },
                  body: JSON.stringify({ SITIO: data.SITIO, SMP: data.SMP, updates }),
              });
      
              if (!response.ok) {
                  const errorText = await response.text();
                  throw new Error(errorText);
              }
      
              console.log('Data successfully saved.');
              await loadTableData();
          } catch (error) {
              console.error('Error saving data:', error.message);
          }
      }
      
  5. Server-Side (Node.js with Express):

    • The API receives the modified data and updates the corresponding rows in BigQuery:
      const express = require('express');
      const { BigQuery } = require('@google-cloud/bigquery');
      const app = express();
      
      app.use(express.json());
      
      app.put('/api/edit', async (req, res) => {
          const { SITIO, SMP, updates } = req.body;
      
          // Example logic to handle updates in BigQuery
          try {
              const bigquery = new BigQuery();
              const queries = updates.map(update => {
                  return `UPDATE `project-database.table`
                          SET ${update.column} = "${update.value}"
                          WHERE SITIO = "${SITIO}" AND SMP = "${SMP}"`;
              });
      
              await Promise.all(queries.map(query => bigquery.query(query)));
      
              res.status(200).send('Data updated successfully');
          } catch (error) {
              console.error(error);
              res.status(500).send('Error updating data: ' + error.message);
          }
      });
      
      app.listen(8080, () => console.log('Server running on port 8080'));
      

Problem:

Despite trying to filter the data and send only the modified cells, I keep getting the error updates.map is not a function on the server. My goal is to ensure that only the modified cells are updated in BigQuery.

Question:

What could be causing this error, and how can I resolve it to ensure that the data is sent correctly and only the modified cells are updated in BigQuery?

Thanks for your help.


This version includes the full context of your HTML structure, the frontend logic, and the server-side code for updating BigQuery. You can post this on Stack Overflow for assistance.

What I Tried
I implemented a method to capture and filter only the modified cells from an HTML table before sending them to an API. The API is supposed to update the corresponding rows in BigQuery.

What I Expected
I expected the API to receive the filtered data and successfully update the records in BigQuery.

What Actually Happened
The server returned an error, updates.map is not a function, suggesting that updates was not an array, leading to the failure in the update process.

Need Help Creating a Web Page to Process Multiple MNEMONIC Inputs for TON Blockchain [closed]

I’m working on a web-based crypto application and need some help with the following task. I want to create a page where users can input multiple mnemonics, process them, and display the results, specifically for the TON blockchain. The output should include the TON private key and V4R2 address (compatible with Tonkeeper).

Here’s what I have so far:

  1. Input Box: For users to input multiple mnemonics.
  2. Process Button: To trigger the processing of the mnemonics.
  3. Result Display: To show the generated private key and V4R2 address for each mnemonic.
    I’m using the TON blockchain and need to use the Tonkeeper format for addresses.

Specific Questions:

  • How can I handle multiple mnemonics input in a single form field and process them efficiently?
  • What libraries or tools should I use to generate the TON private key and address from the mnemonics?
  • How can I display the results (private key and V4R2 address) in a user-friendly format on the webpage?
  • Any examples or code snippets would be greatly appreciated!

Thank you in advance!

How can I play Widevine encrypted audio in the browser?

I already have everything set up (license, server certificate, media keys, all of that)
I just want to load the entire file into an audio element and have it work.
I can barely even find any documentation on how encryption works with audio/video elements.

I have attempted to use MSE, but it causes a lot of weird arbitrary limitations and problems that don’t make any sense. Even when I had everything working, it still threw an error with longer audio, and when I tried to combat that, it would remove the beginning of the audio to append more. I don’t want to implement dynamically appending when I seek, as it just adds another layer of confusion and things to deal with.

If I try simply setting the src to the encrypted audio URL, it refuses to play at all.

Snowflake sproc for handling dynamic files

Have a need to build an sproc in Snowflake in order to adjust columns in the DB table based on the file that is in the external stage and it’s loaded into a final table. Need to compare columns in case there are more columns or less columns in the .csv then the table need the table to be updated with the columns and loaded the data.

Thanks
Andy

Tried to build it but was getting the following error even though all the columns are text.

Error: SQL compilation error:
Unsupported data type ‘O’.

JS variable from html undefined [duplicate]

I wrote this code 2-3 years ago for a class and it worked perfectly. I know this as I got a perfect score on the assignment it was for. But recently I went back to the program and found that it no longer works. The console says that the variable “letterNumber” is undefined, but two similar variables, “numberNumber” and “speacialNumber” are fine so I’m lost. I am incredibly rusty in Javascript as I havent touched it since this assignment so I was wondering if anyone would be willing to help me find the issue. The code is below

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>replit</title>
    <link href="style.css" rel="stylesheet" type="text/css" />
  </head>
  <body>
  
  <table>
  <tr>
  <td>
    <center>

    <h1>Password Generator</h1>

      <p>Select your desired settings below and the password will automatically generate!</p>


      <div class="subHead"><p>Letter Case Settings:</p></div>

      <div id="radioMixDiv">
          <input id="radioMix" type="radio" name="capCheck" onchange="setLength('mix')"   checked>
            <label for="">Uppercase and Lowercase</label>
      </div>
      <div> 
        <input id="radioUpper" type="radio" name="capCheck" onchange="setLength('caps')">
            <label for="">Uppercase Only</label>
      </div>
      <div id="radioLowerDiv">
        <input id="radioLower" type="radio" name="capCheck" onchange="setLength('lows')">
            <label for="">Lowercase Only</label>
      </div>

      <div class="subHead"><p>Character Number Settings:</p></div>

      <div id="letterNumberDiv">
        <label for="letterNumber">Number of Letters:</label>
        <select name="letterNumber" id="letterNumber" onchange="setLength()"></select>
      </div>
      <div>
        <label for="numberNumber">Number of Numbers:</label>
        <select name="numberNumber" id="numberNumber" onchange="setLength()"></select>
      </div>
      <div id="speacialNumberDiv">
        <label for="speacialNumber">Number of Special Characters:</label>
        <select name="speacialNumber" id="speacialNumber" onchange="setLength()"></select>
      </div>
     
     
      <div>
        <button id="btnRenderPassword" onclick="setLength()">New Password</button>
        <button id="btnCopy" onclick="copyPassword()">Copy</button>
      </div>


      <div id="inputDiv"><input type="text" id="outPassword"></input></div>


        <script src="data.js"></script>
        <script src="script.js"></script>

    </center>
  </td>
  </tr>
  </table>

  </body>
</html>

data.js

var letters = [
  "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"
];

var speacialChars = [
  "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "?", ".", "_", "-"
];

script.js

//App: Password Generator

//Date: 2/25/22


//DOCUMENT OBJECTS
var passLengthDropdown = document.getElementById("passLength");
var radioMix = document.getElementById("radioMix");
var radioLetter = document.getElementById("radioLetter");
var radioNumber = document.getElementById("radioNumber");
var outPassword = document.getElementById("outPassword");

//VARIABLES
var password = [];
var passLength = "";
var capsSetting = "mix";

//INIT
init();


//FUNCTIONS
//Start program by running the setLength and fillDropdowns functions
function init() {
  fillDropdowns();
  setLength();
}


//Cycle through the three dropdowns (letters, numbers, and specials), and fill them with numbers up to 50.
function fillDropdowns() {
  for (i = 0; i < 51; i++)
  {
    var lengthChild = document.createElement("option");
        lengthChild.innerHTML = i;  
        letterNumber.appendChild(lengthChild);
  }
  for (i = 0; i < 51; i++)
  {
    var lengthChild = document.createElement("option");
        lengthChild.innerHTML = i;  
        numberNumber.appendChild(lengthChild);
  }
  for (i = 0; i < 51; i++)
  {
    var lengthChild = document.createElement("option");
        lengthChild.innerHTML = i;  
        speacialNumber.appendChild(lengthChild);
  }   
}


//Make sure there are multiple letters when mix is checked, clear current password, and start the function to generate a new one
function setLength(radioState) {
  if (document.getElementById("radioMix").checked && letterNumber.value == 1) {
    letterNumber.value = 2;
  }
  outPassword.value = "";

  //Run "createletters" with the argument the user has selected
  if (document.getElementById("radioMix").checked) {
    createLetters("mix");
  } else if (document.getElementById("radioLower").checked) {
    createLetters("lows");
  } else {
    createLetters("caps");
  }
}


//The start of the main portion of the program. It generates a list of random letters in the number of the user's input. It then checks to see what the desired case of the letters is and racts by either leaving the letters untouched, randomly changing some to lowercase, or changing all to lowercase. If a mix of capitilization is chosen the function also checks to make sure there is at least one capital and one lowercase letter, and if there is not it randomly changes one letter's capitilization to accordingly.
function createLetters(radioState) {
var charList = [];

  if ((parseInt(letterNumber.value) > 0)) {
    for (i = 0; i < parseInt(letterNumber.value); i++) {
      charList.push(letters[Math.floor(Math.random() * letters.length)]);
    }

  var tempLetters = "";

  if (radioState == "mix") {
    //generate list of letters. Generate random number, and if 1 leave it if 2 lowercase it. Make sure there is at least 1 upper and 1 lower.
    var lowNumb = 0;
    for (i = 0; i < charList.length; i++) {
      var randomNumb = Math.floor((Math.random() * 2) + 1);
      if (randomNumb == 1) {
        var givenLetter = charList[i];
        givenLetter = givenLetter.toLowerCase();
        charList.splice(i, 1, givenLetter);
        lowNumb += 1;
      }
    }

    //If there are no lowercase letters replace one capital letter with a lowercase one
    if (lowNumb == 0) {
      var tempNumb = (parseInt(charList.length) - 1);
      var temp = charList[tempNumb];
      temp = temp.toLowerCase(); 
      charList.splice(tempNumb);
      charList.push(temp);
    }

    //If there are no capital letters change one letter to be captal
    if (lowNumb == charList.length) {
      var tempNumb = (parseInt(charList.length) - 1);
      var temp = charList[tempNumb];
      temp = temp.toUpperCase(); 
      charList.splice(tempNumb);
      charList.push(temp);
    }
    
  //If lowercase only is selected assign all letters to lowercase
  } else if (radioState == "lows") {
    for (i = 0; i < charList.length; i++) {
      tempLetters += charList[i];
    }
    tempLetters = tempLetters.toLowerCase();
    console.log(tempLetters + " (lowercase)");
    charList = [];
    for (i = 0; i < tempLetters.length; i++) {
      charList.push(tempLetters[i]);
    }
  }
  }

createNumbers(charList);
}


//The function adds a random sequence of numbers to charList in the number that is chosen by the user.
function createNumbers(charList) {
  if ((parseInt(numberNumber.value) > 0)) {
    for (i = 0; i < parseInt(numberNumber.value); i++) {
      charList.push(Math.floor(Math.random() * 9) + 1);
    }
  }

createSpecial(charList);
}


//The function adds a number (selected by the user) of random "special characters" from the speacialChars array to the charList function.
function createSpecial(charList) {
  if ((parseInt(speacialNumber.value) > 0)) {
    for (i = 0; i < parseInt(speacialNumber.value); i++) {
      charList.push(speacialChars[Math.floor(Math.random() * speacialChars.length)]);
    }
  }
  
randomizePassword(charList);
}


//Loop through the list of characters for the password (charList), and randomly re-order it, then run cleanPassword()
function randomizePassword(charList) {
  for (i = 0; i < charList.length; i++) {
    var j = Math.floor(Math.random() * (i + 1));
    var tempStore = charList[i];
    charList[i] = charList[j];
    charList[j] = tempStore;
  }
  console.log(charList);
  cleanPasword(charList);
}


//Copy each value from the array to a new string and display it on the screen.
function cleanPasword(charList) {
  var drawnPass = "";
  for (i = 0; i < charList.length; i++) {
    console.log(charList[i]);
    drawnPass += charList[i];
  }
  outPassword.value = drawnPass;
}


//On "Copy" button click select the password text and copy it to the clipboard
function copyPassword() {
  outPassword.select();
  navigator.clipboard.writeText(outPassword.value);
}

want to pass Ip, country for all http request header and after save all data

When I use that way all the time IP and country pass null in the backend

I need to pass the value for the activity log

I use the backend for Java Spring boot

And use AOP for this

I solve below this way but don’t

Geo Service

export class GeoService {
private geoApiUrl = ‘https://ipinfo.io/json’; // IPinfo.io API

  constructor(private http: HttpClient) {}

  getGeoInfo(): Observable<any> {
    return this.http.get<GeoInfoResponse>(this.geoApiUrl).pipe(
      catchError(error => {
        console.error('Error fetching geo information:', error);
        return throwError(() => new Error('Failed to fetch geo information'));
      })
    );
  }
}
export interface GeoInfoResponse {
  ip: string;
  country: string;
  city: string;
  region: string;
  loc: string; // Latitude and longitude
  org: string; // Organization
  postal: string; // Postal code
  timezone: string;
}

Geo Info Service

export class GeoInfoService {
  private ipSubject = new ReplaySubject<string | null>(1);
  private countrySubject = new ReplaySubject<string | null>(1);

  constructor(private geoService: GeoService) {
    this.loadGeoInfo();
  }

  private loadGeoInfo(): void {
    this.geoService.getGeoInfo().subscribe({
      next: (data: GeoInfoResponse) => {
        this.ipSubject.next(data.ip);
        this.countrySubject.next(data.country);
      },
      error: (error) => {
        console.error('Error loading geo info:', error);
        this.ipSubject.next(null);
        this.countrySubject.next(null);
      },
    });
  }

  getIp(): Observable<string | null> {
    return this.ipSubject.asObservable();
  }

  getCountry(): Observable<string | null> {
    return this.countrySubject.asObservable();
  }
}

Geo Interceptor

export class GeoInterceptor implements HttpInterceptor {

  constructor(private geoInfoService: GeoInfoService) {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return this.geoInfoService.getIp().pipe(
      switchMap(ip =>
        this.geoInfoService.getCountry().pipe(
          map(country => {
            let headers = req.headers;
            if (ip) {
              headers = headers.append('Client-IP', ip);
            }
            if (country) {
              headers = headers.append('Client-Country', country);
            }

            const modifiedReq = req.clone({ headers });
            return modifiedReq;
          }),
          switchMap(modifiedReq => next.handle(modifiedReq))
        )
      )
    );
  }
}

AuthInterceptor

export class AuthInterceptor implements HttpInterceptor {
  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    let authToken = this.authStorageService.getToken();
    if (authToken) {
      const authReq = req.clone({
        setHeaders: { Authorization: 'Bearer ' + authToken },
      });
      return next.handle(authReq);
    } else {
      return next.handle(req);
    }
  }
  
 }

AppModule

@NgModule({
  declarations: [AppComponent],
  bootstrap: [AppComponent],
  imports: [
    BrowserModule,
    AppRoutingModule,
  ],
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: GeoInterceptor, multi: true },
    { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
  ],

})
export class AppModule {}

AppRoutingModule

const routes: Routes = [
  { path: 'login', component: LoginComponent },
  { path: 'register', component: RegistrationComponent },

  {
    path: 'home',
    component: DefaultLayoutComponent,
    canActivate: [AuthenticationGuard],
    children: [
      { path: 'authentication',loadChildren: () =>import('./modules/authentication/authentication.module').then((m) => m.AuthenticationModule),},
      { path: 'test', loadChildren: () => import('./modules/test/test.module').then((m) => m.TestModule),},
    ],
  },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  providers: [{ provide: LocationStrategy, useClass: HashLocationStrategy }],
  exports: [RouterModule],
})
export class AppRoutingModule {}

Chrome Extension: content.js triggered only once whereas “url” is changing

I am new to Chrome Extensions (“CE”) and JS.
Using CE with JS I am scraping data from a website while I visit it (active tab).
It works the first time I navigate a matching url (defined in the manifest.json) but I have to click refresh when I navigate to a new matching URL.

I would like to navigate and the script to run every time the pattern is matched.

my manifest.json file:

{
  "manifest_version": 3,
  "name": "Scraper",
  "description": "Scrape product data from the active tab.",
  "version": "1.0",
  "icons": {
    "16": "abc.png",
    "32": "abc.png",
    "48": "abc.png",
    "128": "abc.png"
  },
  "permissions": ["webNavigation"],
  "content_scripts": [
    {
      "js": [
        "scripts/content.js" 
      ],
      "matches": ["https://*.example.co.uk/search?*"],
      "run_at": "document_idle"
    }
  ]
}

my content.js file is like:

function scrapProductsFromSearch() {

      console.log("Scrapped the page");
  }

I beleive the issue is that I want my app to trigger whenever the “fragment” part has changed ie:

  • https://*.example.co.uk/search?ABC
  • https://*.example.co.uk/search?DEF
    Should trigger the script..

My understanding is that, these 2 urls are not being accounted as different because there is no “/” after the “?”.
Again I am new to this, and correct me if I al wrong.

So I guess the question is how to take into account these changes.
Any help would be much apreciated.
Thank you vm

When a function is the return value of another function, when is that function called? [duplicate]

I am going over Lexical Environments on javascript.info. I can’t determine when the returned function is actually called.

function makeCounter() {
  let count = 0;

  return function() {
    return count++;
  };
}

let counter = makeCounter();

console.log(counter()) // 0
console.log(counter()) // 1

I thought that the first console log would output 1 because I assumed that the return function would be invoked when it was returned, incrementing the value of count from 0 to 1.

The fact that the count has been incremented by the second function call makes me think that the returned function is still invoked some time around the time it is returned.

Is it being invoked when it is returned but the value of count isn’t being updated until after the console log? Or is something else at play?

Eggshell gradients in css

enter image description here

What is the best strategy to creating subtle complex gradients like the attached. I tried to see what the css was in this element, but it may be set in the canvas javascript itself.

I am not sure if this is a linear gradient – or made up of multiple gradients stacked on top of each other with differing degrees of opacity.

Its as if there is a spot of indigo top/left and peach in the bottom/left

https://jsfiddle.net/Ls4dr3bo/1/

body{
    background: rgb(229,232,236);
background: linear-gradient(90deg, rgba(229,232,236,1) 0%, rgba(229,232,236,1) 35%, rgba(231,217,219,1) 74%, rgba(231,221,224,1) 100%);
}


.container{
  height: 100vh;
  width:100%;
}
<div class="container">

</div>

possible html and css used in reference

https://www.exo.inc/iris

jsx

'use client';

import gsap from 'gsap';
import { useLayoutEffect, useRef } from 'react';

import { Section } from '~/components/ui';
import { cx } from '~/utils';

import styles from './ExoIrisGradientTransition.module.scss';

export const ExoIrisGradientTransition = () => {
  const containerRef = useRef(null);

  useLayoutEffect(() => {
    const ctx = gsap.context(() => {
      if (!containerRef.current) return;
      gsap.to('.js__solid', {
        opacity: 1,
        scrollTrigger: {
          trigger: '.js__gradientContainer',
          start: '80% bottom',
          end: 'bottom bottom',
          // markers: true,
          scrub: true,
        },
      });
    }, containerRef);

    return () => {
      ctx.revert();
    };
  }, []);

  return (
    <Section className={styles.container} ref={containerRef}>
      <div className={cx(styles.gradientContainer, 'js__gradientContainer')}>
        <div className={cx(styles.gradient, 'js__gradient')} aria-hidden />
        <div className={cx(styles.solid, 'js__solid')} aria-hidden />
      </div>
    </Section>
  );
};

css

.container {
  position: relative;
  display: flex;
  background: transparent;
  flex-flow: column nowrap;
  z-index: 5;
}

.gradientContainer {
  --container-height: 160vh;
  height: var(--container-height);
  position: relative;
  width: 100%;

  @include landscape {
    --container-height: 200vh;
  }
}

.gradient {
  width: 100%;
  height: var(--container-height);
  background: linear-gradient(
    180deg,
    rgba(236, 194, 111, 0.5) 0%,
    rgba(110, 153, 234, 1) 65%,
    rgba(8, 11, 27, 1) 100%
  );

  @include landscape {
    background: linear-gradient(
      140deg,
      rgba(255, 255, 255, 1) 0%,
      rgba(236, 194, 111, 1) 33%,
      rgba(110, 153, 234, 1) 66%,
      rgba(8, 11, 27, 1) 100%
    );
  }
}

.solid {
  position: absolute;
  top: 0;
  z-index: 2;
  width: 100%;
  height: var(--container-height);
  background: $color-dark-dark-blue;
  opacity: 0;
}

Why http.server does not deliver the data to the CGI script in this basic example?

I am testing the legacy CGI functionality of python http.server module by implementing a “hello world” alike example that sends data from a fictional “add customer” form from the web front end to the backend.
The data is processed by a CGI script which just writes the text received into a file.

This is what I have tried:

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Add New Customer</title>
    <script>
        function submitForm() {

            // Test string to send
            fixedLengthData = "FOO TEST STRING";

            // Post to console
            console.log(fixedLengthData);

            // Create and send POST request to COBOL backend
            fetch('/cgi-bin/customer_add', {
                method: 'POST',
                headers: {
                    'Content-Type': 'text/plain'
                },
                body: fixedLengthData
            })
            .then(response => {
                if (!response.ok) {
                    throw new Error('Network response was not ok ' + response.statusText);
                }
                return response;
            })
            .catch(error => {
                console.error('There was a problem with the fetch operation:', error);
            });
        }
    </script>
</head>
<body>
    <h1>Add New Customer</h1>
    <form id="customerForm" onsubmit="event.preventDefault(); submitForm();">
        <label for="CUSTOMER-ID">Customer ID:</label>
        <input type="text" id="CUSTOMER-ID" name="CUSTOMER-ID" maxlength="4" required><br>
        <label for="CUSTOMER-NAME">Customer Name:</label>
        <input type="text" id="CUSTOMER-NAME" name="CUSTOMER-NAME" maxlength="50" required><br>
        <label for="CUSTOMER-EMAIL">Email:</label>
        <input type="email" id="CUSTOMER-EMAIL" name="CUSTOMER-EMAIL" maxlength="100"><br>
        
        <button type="submit">Add Customer</button>
    </form>
</body>
</html>

This is the backend CGI script located under cgi-bin folder:

#!/bin/sh

# Open the file 'test.txt' for writing
exec 3> test.txt

# Read all input from stdin into a single variable
input=$(cat)

# Write the input to the file
echo "$input" >&3

# Close the file
exec 3>&-

Running the http.server and accessing the CGI script at the browser gets the CGI script launched but:

  1. it never ends and
  2. writes nothing to the text file

I am wondering if it could be that no data is provided to the CGI script in the standard input or the script not finishing makes the data written to file not being flushed.

$ python3 -m http.server --bind localhost --cgi 8000
Serving HTTP on ::1 port 8000 (http://[::1]:8000/) ...
::1 - - [30/Aug/2024 02:39:27] "POST /cgi-bin/customer_add HTTP/1.1" 200 -

ps shows that the CGI process does not end.

$ ps

user 24194   0.0  0.0    13556    2644 10  S+   02:39       0:00.00 /bin/sh /home/user/test/cgi-bin/customer_add

The CGI script itself seems to work as stand alone:

$ echo -n "FOO TEST STRING" | ./customer_add
$ ls -ltr
total 64
-rwxrwxr-x  1 user user    209 Aug 30 02:37 customer_add
-rw-rw-r--  1 user user      4 Aug 30 02:37 test.txt
$ cat test.txt
FOO TEST STRING

Why the CGI process gets stuck, could it be that it is not receiving the data?

I’m getting this error and i don’t know why ” Cannot destructure property ‘cloud_cover’ of ‘data’ as it is undefined.”

This is the block of code that is getting me that error

const CurrentWeather = ({ data }) => {
  const {
    cloud_cover,
    feels_like,
    humidity,
    icon_num,
    precipitation,
    summary,
    temperature,
    uv_index,
    visibility,
    wind,
  } = data;

// full code

import WeatherIcon from "./WeatherIcon";
import "../styles/components/CurrentWeather.scss";

const units = {
  precipitation: "mm",
  wind_speed: "km/h",
  humidity: "%",
  uv_index: "",
  cloud_cover: "%",
  visibility: "km",
};

const CurrentWeather = ({ data }) => {
  const {
    cloud_cover,
    feels_like,
    humidity,
    icon_num,
    precipitation,
    summary,
    temperature,
    uv_index,
    visibility,
    wind,
  } = data;

  const otherInfoWidgets = [
    {
      id: 0,
      icon: "droplet",
      name: "Precipitation",
      value: Math.round(precipitation.total),
      unit: units.precipitation,
    },
    {
      id: 1,
      icon: "wind",
      name: "Wind",
      value: Math.round(wind.speed),
      unit: units.wind_speed,
    },
    {
      id: 2,
      icon: "moisture",
      name: "Humidity",
      value: Math.round(humidity),
      unit: units.humidity,
    },
    {
      id: 3,
      icon: "sunglasses",
      name: "UV index",
      value: Math.round(uv_index),
      unit: units.uv_index,
    },
    {
      id: 4,
      icon: "clouds-fill",
      name: "Clouds cover",
      value: Math.round(cloud_cover),
      unit: units.cloud_cover,
    },
    {
      id: 5,
      icon: "eye",
      name: "Visibility",
      value: Math.round(visibility),
      unit: units.visibility,
    },
  ];

  return (
    <div className="CurrentWeather">
      <div className="temperature">
        <div className="weather-icon">
          <WeatherIcon iconNumber={icon_num} summary={summary} />
        </div>
        <div className="value">
          <div className="real">
            {Math.round(temperature)} {units.temperature}
          </div>
          <div className="feels_like">
            feels like {Math.round(feels_like)} {units.temperature}
          </div>
        </div>
        <div className="summary">{summary}</div>
      </div>
      <div className="other-infos">
        {otherInfoWidgets.map(({ id, name, icon, value, unit }) => (
          <div className="widget" key={id}>
            <div className="widget-container">
              <div className="info">
                <div className="icon">
                  <i className={`bi bi-${icon}`}></i>
                </div>
                <div className="value">
                  {value} {unit}
                </div>
              </div>
              <div className="name">{name}</div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
};

export default CurrentWeather;

Module not found: Can’t resolve ‘../../contexts/ProfileDataContext’ in ‘/workspace/today/src/pages/profiles’

I am trying to make a profile data context here is the code for it

import { createContext, useContext, useEffect, useState } from "react";
import { axiosReq } from "../api/axiosDefaults";
import { useCurrentUser } from "../contexts/CurrentUserContext";

const ProfileDataContext = createContext();
const SetProfileDataContext = createContext();

export const useProfileData = () => useContext(ProfileDataContext);
export const useSetProfileData = () => useContext(SetProfileDataContext);

export const ProfileDataProvider = ({ children }) => {
  const [profileData, setProfileData] = useState({
    // we will use the pageProfile later!
    pageProfile: { results: [] },
    popularProfiles: { results: [] },
  });

  const currentUser = useCurrentUser();

  useEffect(() => {
    const handleMount = async () => {
      try {
        const { data } = await axiosReq.get(
          "/profiles/?ordering=-followers_count"
        );
        setProfileData((prevState) => ({
          ...prevState,
          popularProfiles: data,
        }));
      } catch (err) {
        console.log(err);
      }
    };

    handleMount();
  }, [currentUser]);

  return (
    <ProfileDataContext.Provider value={profileData}>
      <SetProfileDataContext.Provider value={setProfileData}>
        {children}
      </SetProfileDataContext.Provider>
    </ProfileDataContext.Provider>
  );
};

and i get no errors until i add it to my popularprofiles.js which is this

import React from "react";
import { Container } from "react-bootstrap";
import Styles from "../../App.module.css";
import Asset from "../../components/Asset";
import { useProfileData } from "../../contexts/ProfileDataContext";
import Profile from "./Profile";

const PopularProfiles = ({ mobile }) => {
  const { popularProfiles } = useProfileData();

  return (
    <Container
      className={`${Styles.Content} ${
        mobile && "d-lg-none text-center mb-3"
      }`}
    >
      {popularProfiles.results.length ? (
        <>
          <p>Most followed profiles.</p>
          {mobile ? (
            <div className="d-flex justify-content-around">
              {popularProfiles.results.slice(0, 4).map((profile) => (
                <Profile key={profile.id} profile={profile} mobile />
              ))}
            </div>
          ) : (
            popularProfiles.results.map((profile) => (
              <Profile key={profile.id} profile={profile} />
            ))
          )}
        </>
      ) : (
        <Asset spinner />
      )}
    </Container>
  );
};

export default PopularProfiles;

and once i do that i get this error Failed to compile.

./src/pages/profiles/PopularProfiles.js
Module not found: Can’t resolve ‘../../contexts/ProfileDataContext’ in ‘/workspace/today/src/pages/profiles’

i have tried everything i can think of and tried to rewrite the path multiple times but i am having no hoping i was hoping someone could help me

Error using Firebase Auth through vscode Live Server extension

I am trying to test my firebase app using vscodes live server extension, but when i try logging in it gives unauthorized domain error.
Im using vanilla js firebase skd.
This is the url: http://127.0.0.1:5500/
When i tried this on replit, using thier domain for my repl it worked completely fine, so i think it might be an issue with the extension.

When i try adding the url to firebase authorized domains for auth, it says “Invalid domain”.
Ive tried using a different browser, removing browser extensions, checking my config, i even created a whole new firebase project. How do i fix this? Or is their an alternative to run it on localhost?

How to trigger multiple animations when the user clicks on the (link)

I have this Html code and I want all the animations to be played after clicking on the link :

document.querySelector('.play').addEventListener('click', function() {
  document.querySelector('.trans-up').style.animationPlayState = 'running';
  document.querySelector('.trans-mid').style.animationPlayState = 'running';
  document.querySelector('.trans-down').style.animationPlayState = 'running';
});
.trans-up {
  animation: trans-up-anim 1.8s forwards;
}

.trans-down {
  animation: trans-dow -anim 1.5s forwards;
}

.trans-mid {
  animation: trans-down-anim 1.3s forwards;
}

@keyframes trans-up-anim {
  0% {
    top: -100%
  }
}

@keyframes trans-down-anim {
  0% {
    bottom: -100%
  }
}
<a class="play">click on me<a>

<div class="trans-up"></div>

<div class="trans-mid"></div>

<div class="trans-down"></div>

How can I display chart js graph data line like a heartbeat design?

I make an graph for my project. Everythings seems working well. I just wanted to show my graph data line like a heart beat design. If i manually do that, seems like i need to insert so many data.

I tried to enter data manually, however the graph cannot handle too much data, and my design is similar to a heartbeat design.

My code –

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
    <style>
        .chart-container {
            width: 100%;
            height: auto;
            margin: 0 auto;
        }

        .chart-container canvas {
            background: #ffffff;
            width: 100% !important;
            height: 100% !important;
        }

        .chart-toggle,
        .chart-toggle.active {
            display: flex;
            align-items: center;
            gap: 8px;
            cursor: pointer;
            opacity: 0.5;
            transition: opacity 0.3s;
        }

        .chart-toggle.active {
            opacity: 1;
        }

        .toggle-group {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 16px;
        }

        .chart-toggle span {
            color: #101839;
            font-size: 14px;
            font-style: normal;
            font-weight: 400;
            line-height: 34px;
            text-transform: capitalize;
            transition: 0.2s ease-in-out;
        }
    </style>
</head>
<body>
    <div class="row justify-content-center">
        <div class="col-5">
            <div class="card">
                <div class="chart-container">
                    <canvas id="dataChart"></canvas>
                </div>
                <div class="toggle-group">
                    <div class="chart-toggle active" id="toggleCurrentMonth">
                        <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none">
                            <circle cx="6" cy="6" r="4.5" fill="white" stroke="#5159A7" stroke-width="3"/>
                        </svg>
                        <span>Current Month</span>
                    </div>
                    <div class="chart-toggle active" id="togglePreviousMonth">
                        <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none">
                            <circle cx="6" cy="6" r="4.5" fill="white" stroke="#F8C140" stroke-width="3"/>
                        </svg>
                        <span>Previous Month</span>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script>
        const ctx = document.getElementById('dataChart').getContext('2d');

        const chartData = {
            labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'],
            datasets: [
                {
                    label: 'Current Month',
                    data: [1200, 6200, 2000, 6900, 3800, 8200, 2200, 6000],
                    borderColor: '#4F45B6',
                    borderWidth: 5,
                    fill: false,
                    tension: 0, // Smooth curve effect
                    pointRadius: 0,
                    pointHoverRadius: 5,
                    order: 1,
                },
                {
                    label: 'Previous Month',
                    data: [3800, 2700, 2800, 1400, 6000, 5500, 5600, 3800],
                    borderColor: '#F8C140',
                    borderWidth: 5,
                    fill: false,
                    tension: 0,
                    pointRadius: 0,
                    pointHoverRadius: 5,
                    order: 2,
                }
            ]
        };

        const chart = new Chart(ctx, {
            type: 'line',
            data: chartData,
            options: {
                responsive: true,
                scales: {
                    y: {
                        beginAtZero: false,
                        min: 1000,
                        max: 10000,
                        ticks: {
                            stepSize: 2000,
                            callback: function(value) {
                                return value >= 1000 ? value / 1000 + 'k' : value;
                            },
                            font: {
                                family: 'Gilroy-Medium',
                                size: 18,
                                style: 'normal',
                                weight: '400'
                            },
                            color: '#101839',
                            lineHeight: 34,
                            textTransform: 'capitalize',
                            opacity: 0.4,
                            padding: 16
                        },
                        grid: {
                            display: false
                        },
                        border: {
                            display: false
                        }
                    },
                    x: {
                        ticks: {
                            display: false
                        },
                        grid: {
                            display: false
                        }
                    }
                },
                plugins: {
                    legend: {
                        display: false
                    },
                    tooltip: {
                        enabled: false,
                        intersect: false,
                        mode: 'index',
                        external: function(context) {
                            const { chart, tooltip } = context;
                            const tooltipEl = document.querySelector('.chartjs-tooltip') || document.createElement('div');

                            if (!document.querySelector('.chartjs-tooltip')) {
                                tooltipEl.classList.add('chartjs-tooltip');
                                tooltipEl.style.position = 'absolute';
                                tooltipEl.style.pointerEvents = 'none';
                                tooltipEl.style.color = '#fff';
                                tooltipEl.style.padding = '10px 28px';
                                tooltipEl.style.borderRadius = '10px';
                                tooltipEl.style.fontSize = '20px';
                                tooltipEl.style.fontFamily = 'Arial, sans-serif';
                                tooltipEl.style.zIndex = 1000;
                                document.body.appendChild(tooltipEl);
                            }

                            if (tooltip.opacity === 0) {
                                tooltipEl.style.opacity = 0;
                                return;
                            }

                            const datasetIndex = tooltip.dataPoints[0].datasetIndex;
                            tooltipEl.style.backgroundColor = chartData.datasets[datasetIndex].borderColor;

                            const tooltipData = tooltip.dataPoints.map(dp => {
                                if (dp.datasetIndex === datasetIndex) {
                                    return `<div>${dp.formattedValue}</div>`;
                                }
                                return '';
                            }).join('');
                            tooltipEl.innerHTML = tooltipData;

                            const position = chart.canvas.getBoundingClientRect();
                            tooltipEl.style.opacity = 1;
                            tooltipEl.style.left = `${position.left + window.pageXOffset + tooltip.caretX}px`;
                            tooltipEl.style.top = `${position.top + window.pageYOffset + tooltip.caretY}px`;
                        }
                    }
                },
                animation: {
                    onComplete: function() {}
                },
                elements: {
                    point: {
                        radius: function(context) {
                            return context.active ? 5 : 0;
                        }
                    }
                }
            },
            plugins: [{
                beforeDatasetsDraw(chart) {
                    const chartArea = chart.chartArea;
                    const yScale = chart.scales.y;
                    const ctx = chart.ctx;

                    const yLabels = yScale.ticks.map(tick => tick.value);

                    ctx.save();
                    ctx.strokeStyle = '#A098AE';
                    ctx.lineWidth = 1;
                    ctx.setLineDash([6, 6]);

                    yLabels.forEach(label => {
                        const yPos = yScale.getPixelForValue(label);
                        ctx.beginPath();
                        ctx.moveTo(chartArea.left, yPos);
                        ctx.lineTo(chartArea.right, yPos);
                        ctx.stroke();
                    });

                    ctx.restore();
                }
            },
            {
                id: 'verticalLinePlugin',
                beforeDraw: function(chart) {
                    const ctx = chart.ctx;
                    const tooltip = chart.tooltip;
                    const chartArea = chart.chartArea;

                    if (tooltip.opacity === 0) {
                        return;
                    }

                    const tooltipX = tooltip.caretX + chartArea.left;
                    const yScale = chart.scales.y;

                    const datasetIndex = tooltip.dataPoints[0].datasetIndex;
                    const datasetColor = chartData.datasets[datasetIndex].borderColor;

                    ctx.save();
                    ctx.strokeStyle = datasetColor;
                    ctx.lineWidth = 2;
                    ctx.setLineDash([0, 0]);
                    ctx.beginPath();
                    ctx.moveTo(tooltipX, chartArea.top);
                    ctx.lineTo(tooltipX, chartArea.bottom);
                    ctx.stroke();
                    ctx.restore();
                }
            }]
        });

        document.getElementById('toggleCurrentMonth').addEventListener('click', function() {
            chart.data.datasets[0].hidden = !chart.data.datasets[0].hidden;
            chart.update();
            this.classList.toggle('active');
        });

        document.getElementById('togglePreviousMonth').addEventListener('click', function() {
            chart.data.datasets[1].hidden = !chart.data.datasets[1].hidden;
            chart.update();
            this.classList.toggle('active');
        });
    </script>
</body>
</html>

This is the heartbeat design I wanted to exhibit in my graph data – enter image description here