‘addEventListener’ does not work for HTML Web Component

I made web component like below.

Webtest.js

class Webtest extends HTMLElement {
    constructor() {
        super();
    }

    connectedCallback() {
        this.attachShadow({mode: 'open'});
        this.shadowRoot.innerHTML = `
            <style>
                .special {
                    color: green; /* Active link styling */
                    font-weight: bold;
                }
            </style>

            <a id="testId" href="/mypath/index.html">textA</a>
            <a id="testId" href="/mypath/subfolderA/subfolderA.html">textB</a>
            <a id="testId" href="/mypath/subfolderB/subfolderB.html">textC</a>
            <a id="testId" href="/mypath/subfolderC/subfolderC.html">textD</a>
        `;

        const links = this.shadowRoot.querySelectorAll("#testId");
        
        links.forEach(link => {
            link.addEventListener('click', () => {
                this.shadowRoot.querySelector('.special')?.classList.remove('special');
                link.classList.add('special');
            });
        });
    }
}
customElements.define('webtest-component', Webtest);

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="color-scheme" content="dark">
    <script src="./Webtest.js"></script>
</head>

<body>
    <webtest-component></webtest-component>    
</body>

</html>

I have 4 hyperlinks on top of page like this.
enter image description here

I want to highlight the text of last clicked link (one of textA, textB, textC, textD) by inserting special class to last clicked link. But it does not work.

What I tried:
Use ‘addEventListener’ to get the click effect.
click effect:

  1. Remove ‘special’ class from last clicked one.
  2. Add ‘speical’ class to last clicked one.
  3. Since ‘special’ class is defined in style section, it should be highlighted.

Expecting result:
After clicking each text, each text should be highlighted as green color and bold.

Thank you for your help!


According to Nick and Bravo’s help, this is what’s happening. (Thank you very much!)

After clicking page, class properly gets updated but the page redirects to another page and gets refreshed.

So the updated class by the JS only lasts momentarily before the page refreshes.

I want to navigate to each page AND highlight the text of last clicked link.
I want to keep my format as it is.
Any suggestions would be really appriciated!
If you think it is not possible, kindly share as well!
Thank you.

Best Practice for Securing Access Token Server Side

I am looking for some best practices regarding security of an access token. I am building a React / Next JS 14 app and I am using a third party to retrieve financial data from a user’s bank account (Plaid), and one of the things that is sent back when they connect a bank account is an access token. This access token is a permanent identifier of the account / user, and does not expire. I have stored it in the database on the user’s table; however, I don’t know exactly how to use it.

I know it is bad security to expose the access token on the client side; but does this mean that every time I perform a plaid request on the server side, I first have to make a call to my database (based on something like user id), to get the access token? This sounds sort of tedious and inefficient to have to make this same database call for all of my plaid calls to get the access token, but is this just best practice and something I have to put up with? Or is there some sort of way to cache the access token server side for reuse? I know of caching using local, session, and cookies on the browser, but again that is client side and insecure. I am not sure what to do here. Any thoughts sure would be helpful. Thanks!!

Is there any way to show LaTeX in Markdown – React Native

I’m building an AI assistant app and have been struggling to display LaTeX content alongside Markdown-rendered text. Currently, I’m using react-native-markdown-display for Markdown support and the (deprecated) react-native-math-view for LaTeX.

One solution I attempted was to parse the content with a regex to split out Markdown vs. LaTeX segments, then conditionally render them using <Markdown /> or <MathView />. While this works to some extent, it introduces significant alignment and formatting issues.

Below is my current MessageRenderer component, which implements this approach:

import React from 'react';
import {StyleSheet, Text, View} from 'react-native';
import MathView, {MathText} from 'react-native-math-view';
import {textStyle} from "../styles/common.style";
import Markdown from "react-native-markdown-display";
import {MsgType} from "./class/MessageItem";

const MessageRenderer = ({message, type}) => {
    const parts = parseMessage(message);
    
    return (
        <View style={styles().main}>
            {parts.map((part, index) => {
                if (part.type === 'text') {
                    return (
                        <Markdown 
                            key={index} 
                            style={{ body: type === MsgType.USER ? styles().normalText : styles().assistantNormalText }}
                        >
                            {part.content}
                        </Markdown>
                    );
                } else if (part.type === 'math') {
                    return (
                        <MathView
                            key={index}
                            math={part.content}
                            style={styles().mathText}
                        />
                    );
                }
                return null;
            })}
        </View>
    );
};

const parseMessage = (message) => {
    const regex = /\(([sS]*?)\)|\[([sS]*?)\]/g; // Matches math expressions within (...) or [...]
    const parts = [];
    let lastIndex = 0;
    
    try {
        message.replace(regex, (match, group1, group2, index) => {
            // Add text content before the current match
            if (lastIndex < index) {
                parts.push({ type: 'text', content: message.slice(lastIndex, index) });
            }
            
            // Add the matched math content
            const formula = group1 || group2; 
            parts.push({ type: 'math', content: formula });
            
            // Update the lastIndex to the end of the current match
            lastIndex = index + match.length;
        });
        
        // Add any remaining text after the last match
        if (lastIndex < message.length) {
            parts.push({ type: 'text', content: message.slice(lastIndex) });
        }
    } catch (e) {
        console.log("error", e);
        return parts;
    }
    
    return parts;
};

const styles = () => {
    return StyleSheet.create({
        main: {
            flexDirection: 'row',
            flexWrap: 'wrap',
            alignItems: 'center'
        },
        normalText: {
            ...textStyle.Body_4,
            color: 'white'
        },
        mathText: {
            ...textStyle.Body_4,
            marginHorizontal: 2,
            color: 'white'
        },
        assistantNormalText: {
            ...textStyle.Body3,
            color: 'white'
        }
    });
};

export default MessageRenderer;

Sample Test Data

const message = `

- This is a paragraph with some inline math: \(E = mc^2\).

- Some text with inline math \(a^2 + b^2 = c^2\)

- And block math

\[
e = sum_(n=0)^oo 1/n!
\]

\[
\int_{a}^{b} x^2 dx
\]

Here is a JavaScript code block:

```javascript
function greet() {
  console.log("Hello, world!");
}
```

And some more inline math: \(a^2 + b^2 = c^2\).
`;

Question
Is there a more robust or straightforward method to render both Markdown and LaTeX together in React Native without resorting to manually parsing the content via regex?

Cómo hacer que el carrito de una pagina de Compras muestre la cantidad de productos y los productos? [closed]

Estoy construyendo un proyecto de carrito de compras. He avanzado bastante,

  • Ya revisé la sintaxis de todos los componentes, y me parecen, están bien.

  • Pruebas a través de la consola para verificar si se está llamando correctamente el dispatch, y si lo está haciendo.

  • El reducer está retornando un nuevo estado correctamente.

  • Se renderizan en el navegador los elementos

Sin embargo, aún no logro que el carrito de compras realicé la acción de mostrar el contenido, los ítems y la suma de los mismos; tal como lo cree en el componente CartPage.jsx, y cuando voy agregando productos solo me muestra que existe un ítem en el icono del carrito.


    import { useContext } from "react"
    import { CartContext } from "../context/CartContext"
    
    
    export const CartPage = () => {
    
      const { shoppingList, increaseItem, decreaseItem, removePurchase } = useContext(CartContext)
      console.log("Shopping list in CartPage:", shoppingList);
      
      const calculateTotal = () => {
        return shoppingList.reduce((total, item) => total + item.price * item.quantity, 0).toFixed(2) 
      }
      
      const handlePrint = () => {
      //  print()
      };
    
      return ( 
        <>
          <table className="table">
            <thead>
              <tr>
                <th scope="col">Name</th>
                <th scope="col">Price</th>
                <th scope="col">Quantity</th>
                <th scope="col">Remove</th>
              </tr>
            </thead>
            <tbody>
              {
                shoppingList.map(item => (
                  <tr key={item.id}>
                    <th>{item.title}</th>
                    <td>{item.price}</td>
                    <td>{item.quantity}</td>
                    <td>
                      <button className="btn btn-outline-primary"
                      onClick={ () => decreaseItem(item.id) }>-</button>
                      <button className="btn btn-primary"> {item.quantity} </button>
                      <button className="btn btn-outline-primary"
                      onClick={ () => increaseItem(item.id) }>+</button>
                    </td>
                    <td>
                      <button
                      type="button"
                      className="btn btn-danger"
                      onClick={()=>removePurchase(item.id)}>
                      Remove
                      </button>
                      </td>
                  </tr>
                ))
              };
    
              <th> <b>TOTAL: </b> </th>
              <td></td>  
              <td></td>  
              <td>${calculateTotal()}</td>  
    
            </tbody>
          </table>
    
          <div className="d-grid gap-2">
            <button 
            className="btn btn-primary"
            onClick={handlePrint}
            disabled={shoppingList>1}
            > Buy </button>
          </div>
    
        </>
      )
    }


    import './App.css';
    import { Route, Routes, Navigate } from 'react-router-dom';
    import { NavBar } from './Components/NavBar';
    import { ShoppingPage } from './Pages/ShoppingPage';
    import { CartPage } from './Pages/CartPage';
    import { ProductsProvider } from './context/ProductsProvider';
    import { CartProvider } from './context/CartProvider';
    
    function AppCart() {
      return (
        <ProductsProvider>
          <CartProvider>
            <NavBar> </NavBar>
            <div className="container">
              <Routes>
                <Route path='/' element={<ShoppingPage></ShoppingPage>}></Route>
                <Route path='/little cart' element={<CartPage></CartPage>}></Route>  
                <Route path='/*' element={<Navigate to='/' />}></Route> 
              </Routes> 
            </div>    
            </CartProvider>  
        </ProductsProvider>
      );
    }
    
    export default AppCart;

  • En la depuración en consola con (“Add Purchase:”, action.pyload, state); refleja objeto en consola, las características solicitadas y la cantidad es un número que aumenta conforme vas adicionando productos.

  • La prueba realizada con console.log “Adding product:” en el shoppingList presenta los datos correctamente

  • El estado shoppingList refleja los cambios en consola y el quantity está actualizando los cambios


    import { CartContext } from "./CartContext";
    import { useReducer } from "react";
    
    const initialState = []
    
    export const CartProvider = ({ children }) => {
        
    const shoppingReducer = (state = initialState, action = {}) => {
        console.log("Reducer action:", action);
        switch (action.type) {
            case '[CART Add Purchase]':
                console.log("Add Purchase Reducer State:", state);
                console.log("Add Purchase:", action.payload, state);
                const existingProduct = state.find(item => item.id === action.payload.id);
                if (existingProduct) {
                    return state.map(item =>
                        item.id === action.payload.id
                            ? {...item, quantity: item.quantity + 1}
                            : item
                     );
                } else {
                    return [...state, {...action.payload, quantity: 1 }];
                }
                           
            case '[CART] Increase item Purchase': // TODO: Add quantity and to modify
                console.log("Increase Reducer State:", state);
                        return state.map(item => 
                            item.id === action.payload 
                            ? {...item, quantity: item.quantity + 1}
                            : item
                        );
                        
            case '[CART] Decrease item Purchase': // TODO: Add quantity and to modify
                        return state.map(item => 
                            item.id === action.payload 
                            ? {...item, quantity: item.quantity - 1 }
                            : item
                        );
    
            case '[CART] Remove Purchase':
                return state.filter(item => item.id !== action.payload)
    
            default:
                return state;
        }
    }; 
    
    
        const [shoppingList, dispatch] = useReducer(shoppingReducer, initialState)
        console.log("Shopping list in CartPage:", shoppingList);
    
        const addPurchase = (product) => {
            console.log("Adding product:", product);
            const action = {
                type: '[CART Add Purchase]',
                payload: product 
            } 
            dispatch(action)    
        }
    
        const increaseItem = (id) => { 
            const action = {
                type: '[CART] Increase item Purchase',
                payload: id
            }              
            dispatch(action)
            console.log("Increasing item with ID:", id); // Depuration
            dispatch({ type: '[CART] Increase item Purchase', payload: id });
    
        };
    
        const decreaseItem = (id) => {
            const action = {
                type: '[CART] Decrease item Purchase',
                payload: id
            }                         
            dispatch(action)    
        };
    
        const removePurchase = (id) => { 
            const action = {
                type: '[CART] Remove Purchase',
                payload: id
            }          
            dispatch(action)    
        };
    
    
      return (
        <CartContext.Provider value={{shoppingList, addPurchase, increaseItem, decreaseItem, removePurchase}} >
            {children}
        </CartContext.Provider>
      )
    } 

Una parte de la Impresión en consola:

    Adding product: {purchase: {…}}purchase: category: "men's clothing"description: "Your perfect pack for everyday use and walks in the forest. Stash your laptop (up to 15 inches) in the padded sleeve, your everyday"id: 1image: "https://fakestoreapi.com/img/81fPKd-2AYL._AC_SL1500_.jpg"price: 109.95rating: {rate: 3.9, count: 120}title: "Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops"[[Prototype]]: Object[[Prototype]]: Object
    CartProvider.jsx:9 Reducer action: {type: '[CART Add Purchase]', payload: {…}}
    CartProvider.jsx:12 Add Purchase Reducer State: [{…}]
    CartProvider.jsx:13 Add Purchase: {purchase: {…}} [{…}]0: purchase: {id: 1, title: 'Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops', price: 109.95, description: 'Your perfect pack for everyday use and walks in th…to 15 inches) in the padded sleeve, your everyday', category: "men's clothing", …}quantity: 5[[Prototype]]: Objectlength: 1[[Prototype]]: Array(0)
    CartProvider.jsx:50 Shopping list in CartPage: [{…}]
    CartProvider.jsx:9 Reducer action: {type: '[CART Add Purchase]', payload: {…}}
    CartProvider.jsx:12 Add Purchase Reducer State: [{…}]
    CartProvider.jsx:13 Add Purchase: {purchase: {…}} [{…}]
    CartProvider.jsx:50 Shopping list in CartPage: [{…}]0: purchase: {id: 1, title: 'Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops', price: 109.95, description: 'Your perfect pack for everyday use and walks in th…to 15 inches) in the padded sleeve, your everyday', category: "men's clothing", …}quantity: 6[[Prototype]]: Objectlength: 1[[Prototype]]: Array(0)
  • Ya revisé el map. en el shoppingList (componente CartPage) y, validé enviando directamente { …product} en el componente CartProvider, pero aún nada.

Esta es la construcción de mi ShoppingPage:


    import React, { useContext } from "react";
    import { Card } from "../Components/Card";
    import { ProductsContext } from "../context/ProductsContext";
    import { CartContext } from "../context/CartContext";
    
    export const ShoppingPage = () => {
      
      const { products } = useContext(ProductsContext);
    
      const handleAdd = ( purchase ) =>{
        addPurchase({
          purchase
        });
      };  
      const handleRemove = (id) =>{
        removePurchase(id)
      };
    
      const {
        addPurchase,
        removePurchase,
      } = useContext(CartContext);
    
      
      return (
        <>
          <h1>Shopping: </h1>
          <hr />
    
          {products.map(product => (
            <Card
              key={product.id}
              image={product.image}
              title={product.title}
              description={product.description}
              price={product.price}
              handleAdd={() => handleAdd(product)}
              handleRemove={() => handleRemove(product.id)}
            >
    
            </Card>
          ))};
        </>
      );
    }

How can I start search after setting value of search field?

I am trying to set the value of a search box using JavaScript in Chrome’s console, as shown in this screenshot:

enter image description here

I use the following code to set the value:

document.querySelector("body > main > eup-orders > div > div > div > div.table-header.form-inline.clearfix.with-search > form > div > div > input").value = "Hello World";

Next, I want to trigger the search by clicking the search button, as shown in this screenshot:

enter image description here

Here’s the code I use to click the button:

document.querySelector("#btn-search").click();

The problem: Although the value is successfully set in the search field, the search does not start unless I manually click inside the search field.

Question: Is there a way to programmatically trigger the update of the search field so it works without manual interaction?
Alternatively, is it possible to simulate pressing the Enter key?

Javascript AJAX request with 2 different return types

Is it possible to return 2 different types by an AJAX request?
I created a form with method post. The PHP file creates a PDF file what is returned to the JavaScript file and is automatically downloaded.

But I want also return an array to the same JavaScript file with messages like errors or a notice.

Can I do this in one call or is there a second call needed?

var form = event.target;
var formData = new FormData(form);
fetch(url,{
    method: 'post',
    body: formData
}).then(response => response.blob()).then(response => {
    const blob = new Blob([response], {type: 'application/pdf'});
    const downloadUrl = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = downloadUrl;
    a.download = formData.getAll("invoicenumber")+".pdf";
    document.body.appendChild(a);
    a.click();
});

PHP

$createPdf = new CreatePdf;
$response['msg'] = 'PDF is created!';
header('Content-Type: application/json; charset=UTF-8');
echo json_encode($response);

Expanding Reviews in Vue.js Causes Page to Scroll to the Top

I’m experiencing an issue with a Vue.js component that displays customer reviews. The functionality to expand and collapse individual reviews mostly works, but there’s a problem when revisiting a previously expanded review.

When I perform the following actions:

  1. Expand Review 1 (click “Read Full Review”).
  2. Collapse Review 1.
  3. Expand Review 2.
  4. Go back and expand Review 1 again.

Instead of expanding Review 1 as expected, the page scrolls to the top.

let currentlyExpandedReview: HTMLElement | null = null;

reviewMessages.forEach((message) => {
  const truncated = truncateText(message.textContent || "", 100);

  if (message.textContent && message.textContent.length > 100) {
    message.dataset.fullReview = message.textContent;
    message.textContent = truncated;

    const readMoreLink = document.createElement("a");
    readMoreLink.href = "#";
    readMoreLink.textContent = "more";
    readMoreLink.classList.add("read-more-link");

    const readLessLink = document.createElement("a");
    readLessLink.href = "#";
    readLessLink.textContent = "...less";
    readLessLink.classList.add("read-less-link");

    readMoreLink.addEventListener("click", (event) => {
      event.preventDefault();

      if (currentlyExpandedReview && currentlyExpandedReview !== message) {
        currentlyExpandedReview.classList.remove("expanded");
        const truncatedText = truncateText(
          currentlyExpandedReview.dataset.fullReview || "",
          100
        );
        currentlyExpandedReview.textContent = truncatedText;
        currentlyExpandedReview.appendChild(readMoreLink.cloneNode(true));
      }

      if (message.classList.contains("expanded")) {
        message.classList.remove("expanded");
        message.textContent = truncated;
        message.appendChild(readMoreLink);
        currentlyExpandedReview = null;
      } else {
        message.classList.add("expanded");
        message.textContent =
          message.dataset.fullReview || message.textContent;
        message.appendChild(readLessLink);
        currentlyExpandedReview = message;
      }
    });

    readLessLink.addEventListener("click", (event) => {
      event.preventDefault();
      message.classList.remove("expanded");
      message.textContent = truncated;
      message.appendChild(readMoreLink);
      currentlyExpandedReview = null;
    });

    message.appendChild(readMoreLink);
  }
});

Observations

  • The issue occurs only when re-expanding a previously expanded review.
  • The page scrolls to the top instead of toggling the review.

Steps to Reproduce

  1. Expand and collapse a review.
  2. Expand another review.
  3. Go back and expand the first review again.

Expected Behavior

The first review should expand properly without scrolling the page to the top.

Actual Behavior

The page scrolls to the top instead of expanding the review.

Potential Cause

The issue might be related to the href="#" on the links, causing the browser to scroll to the top by default.

What I Tried

  • Changing href="#" to href="" but that refreshes the entire page.

How can I fix this issue to ensure smooth expansion and collapsing of reviews without the page scrolling to the top? Are there best practices for managing such toggle states in Vue.js with dynamically added event listeners?

Audio fadeout using exponentialRampToValueAtTime in Chrome or Firefox is not reliable

The following code respects the MDN documentation but results in an abrupt mute instead of a 2-second-long fadeout:

const audioContext = new window.AudioContext();
let oscillator;
let gainNode;
document.getElementById("playSweep").addEventListener("click", () => {
    oscillator = audioContext.createOscillator();
    oscillator.type = "sine"; // Sine wave
    oscillator.frequency = 200;
    gainNode = audioContext.createGain();
    gainNode.gain.setValueAtTime(1, audioContext.currentTime);
    oscillator.connect(gainNode);
    gainNode.connect(audioContext.destination);
    oscillator.start();
});
document.getElementById("fadeOut").addEventListener("click", () => {
    gainNode.gain.exponentialRampToValueAtTime(0.001, audioContext.currentTime + 2);
});
document.getElementById("fadeOut2").addEventListener("click", () => {
    gainNode.gain.linearRampToValueAtTime(0.001, audioContext.currentTime + 2);
});
<button id="playSweep">Play Frequency Sweep</button>
<button id="fadeOut">Exp Fade Out</button>
<button id="fadeOut2">Lin Fade Out</button>

Even with the linear version, we can hear a click, it’s not a clean fadeout.

How to do a proper fadeout in JS Web Audio API?

Is it posible using bootstrap-typeahead to append the dropdown to the body, and keep the location?

I have a problem with my typeahead, and the parent container. my parent container has overflow: auto(I needed it for th x axis).
But when I try to use it, it is clipped by overflow like in the image:
image-1

Is there any way to do it like it is for select2? to move the dropdown to body and set the location the same? (image bellow)
image-2

Thank you!

I tried to move it to body and set the top and left properties, but it is not working well.

Why does my convert button do nothing on click?

I’ve been trying to create a unit converter. One of the units is temperature. When I tried to convert from one temperature unit to another, however, the convert button did nothing.

Here is my code:

document.getElementById("confirm").addEventListener("click", function () {
    const inputTemp = parseFloat(document.getElementById("inputTemp").value);
    const inputUnit = document.getElementById("inputUnit").value;
    const outputUnit = document.getElementById("inputUnit").value;

    const conversions = {
        Celsius: {
            Fahrenheit: (temp) => temp * 9 / 5 + 32,
            Kelvin: (temp) => temp + 273.15,
            Celsius: (temp) => temp,
        },
        Fahrenheit: {
            Celsius: (temp) => (temp - 32) * 5 / 9,
            Kelvin: (temp) => (temp - 32) * 5 / 9 + 273.15,
            Fahrenheit: (temp) => temp,
        },
        Kelvin: {
            Celsius: (temp) => temp - 273.15,
            Fahrenheit: (temp) => (temp - 273.15) * 9 / 5 + 32,
            Kelvin: (temp) => temp,
        },

    }

    const result = conversions[inputUnit][outputUnit](inputTemp);
    document.getElementById("outputTemp").textContent = String(result || 0);

});
body {
    font-family: Montserrat, sans-serif;
    display: flex;
    justify-content: center;
    place-items: center;
    height: 100vh;
    background-color: #F4F4F9;

}

.container {
    background-color: #ffffff;
    padding: 20px 30px;
    border-radius: 10px;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    text-align: center;

}

h1 {
    margin-bottom: 20px;
    font-size: 24px;

}

.inputs, .outputs {
    margin-bottom: 15px;

}

input, select, output, button {
    padding: 10px;
    margin: 5px;
    border: 1px solid #ddd;
    border-radius: 8px;
    font-size: 14px;
    transition: 0.5s ease-in-out;

}

button {
    background-color: #007bff;
    color: white;
    border: none;
    cursor: pointer;

}

button:hover {
    background-color: #0056b3

}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Temperature | Unit Converter</title>
    <script src="../js/temp.js" defer></script>
    <link rel="stylesheet" href="../css/converters.css">
</head>
<body>
<div class="container">
    <div class="inputs">
        <input type="number" id="inputTemp" placeholder="Enter Length">
        <select id="inputUnit">
            <option value="celsius">Celsius</option>
            <option value="fahrenheit">Fahrenheit</option>
            <option value="kelvin">Kelvin</option>
        </select>
    </div>
    <div class="outputs">
        <select id="outputUnit">
            <option value="celsius">Celsius</option>
            <option value="fahrenheit">Fahrenheit</option>
            <option value="kelvin">Kelvin</option>
        </select>
        <output id="outputTemp">0</output>
    </div>
    <button id="confirm">Convert</button>
</div>
</body>
</html>

I thought it may be something to do with the DOM not loading in before the elements loaded in so I tried adding to the start of the JS code:
document.addEventListener("DOMContentLoaded", function () {
But that also didn’t work.

Pondjs fixedWindowRollup example needed

Could someone show me how to use the pondjs timeSeries.fixedWindowRollup because I can’t figure out what I’m doing wrong.

I’d like to resample a dataset to have uniform timestamps, so here is the code I’m using based on doc and what I see in the source:

const data = res.map((data: any) => {
    return {
      timestamp: new Date(data.End).getTime(),
      value: data.Value,
    }
  })

  const ts = timeSeries({
    points: data.map((entry: any) => [entry.timestamp, entry.value]),
    columns: ["time", "value"],
    name: "data",
  })
  .fixedWindowRollup({
    window: window(duration("1day")),
    //aggregation: { value: { value: avg() } }, //ts compiler complains
    aggregation: {value: ["value", avg()]},
  })
  .eventList().map(e => {
    return {
      timestamp: e?.timestamp().getTime(), 
      value: e?.get("value")
    }
  });

but the fixedWindowRollup returns that error:

TypeError: Cannot read properties of undefined (reading 'mid')
     at Index.timestamp (project/node_modules/pondjs/src/index.ts:89:32)
     at Event.timestamp (project/node_modules/pondjs/src/event.ts:578:30)
     at project/node_modules/pondjs/src/collection.ts:839:23
     at List.__iterate (project/node_modules/immutable/dist/immutable.js:3370:13)
     at List.forEach (project/node_modules/immutable/dist/immutable.js:4899:19)
     at SortedCollection.forEach (project/node_modules/pondjs/src/collection.ts:425:29)
     at SortedCollection.isChronological (project/node_modules/pondjs/src/collection.ts:837:14)
     at new SortedCollection (project/node_modules/pondjs/src/sortedcollection.ts:43:20)
     at project/node_modules/pondjs/src/windowedcollection.ts:177:51
     at project/node_modules/immutable/dist/immutable.js:2488:31
     at project/node_modules/immutable/dist/immutable.js:2506:18
btw I'm using syntax from version 1.0.0-alpha.0 because latest version didn't work with my ts compiler ...

I also posted the question fixedWindowRollup example needed as an issue directly to the repo but no luck so far unfortunately…
Thanks for any hint!

React Remix UseActionData() Not Triggered by incoming Webhook POST request

I have the action setup in a Remix React project as below to handle both Form Data & a JSON POST request from a webhook.

Both are working as expected and output the data to the console when received. However only the Form request ends up within UseActionData() the JSON post data does not show within this hook.

Does UseActionData() only work with Form data and if so how could I trigger a function when the webhook is successful? Any help is much appreciated!

export async function action({ context, request }) {
  const type = request.headers.get("content-type") 
  console.log(type)

  if (type === "application/json") {
    // Got Data
    console.log("Webhook")
    let data = await request.json()
      
    return ({data})
  } else { 
    const formData = await request.formData();
    const SendParts = formData.get("Query") 
    if (SendParts !== null) {
      const id = await context.new.query(SendParts, {
        cache: CacheShort(),
      });
      return ({ id });
    }
  }
  return  null;
}
// Handle Result of each Action
const actionData =  useActionData();
useEffect(() => {
  if (actionData != null) {
    console.log("ACTION")
    console.log(actionData)
  }
}, [actionData]);

Array pop only works when not assigning to variable?

let channels_history = [0, 0, 1, 0];
let channel = 0;

// wrapped in some button click event handler >>>>>

channel = channels_history.pop();
console.log(channels_history);

\<<<<<

which outputs

[0, 0, 1, 0]

However, if I do

console.log(channels_history.pop());

it works, and I get the desired values.

React pdf viewer not showing the file in its original size and text is very small to read

I am trying to use react-pdf in my app and I have downloaded a code from github for integrating react-pdf in my project. This is working fine and showing the pdf but the size of the pdf is not the original size and it is showing the pdf with 50% decreased size. How can I fix the size problem

const PDFViewer3 = ({
  pdfUrl,
  fieldsToHighlights = [] // Default to empty array
}) => {
  const [numPages, setNumPages] = useState(null)
  const [scales, setScales] = useState([]) // Store scaling factors for each page
  const [pageHeights, setPageHeights] = useState([]) // Store viewport heights for each page

  // Ensure PDF.js worker is set
  pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`

  const onDocumentLoadSuccess = pdf => {
    setNumPages(pdf.numPages)
  }

  const handleRenderSuccess = (page, pageNumber, scale) => {
    const viewport = page.getViewport({ scale: 1 })

    setScales(prevScales => {
      const newScales = [...prevScales]
      newScales[pageNumber - 1] = scale // Save the scale for the page
      return newScales
    })

    setPageHeights(prevHeights => {
      const newHeights = [...prevHeights]
      newHeights[pageNumber - 1] = viewport.height // Save the viewport height for the page
      return newHeights
    })
  }

  const renderHighlights = (pageNumber, scale) => {
    const fieldsOnPage = fieldsToHighlights.filter(
      field => field.page === pageNumber
    )

    if (!fieldsOnPage.length) return null

    return fieldsOnPage.map((field, index) => (
      <div
        key={index}
        style={{
          position: "absolute",
          backgroundColor: "yellow",
          opacity: 0.4,
          left: `${field.x * scale}px`,
          // Adjust the y-coordinate by using the dynamically calculated page height
          top: `${(pageHeights[pageNumber - 1] - field.y - field.height) *
            scale}px`,
          width: `${field.width * scale}px`,
          height: `${field.height * scale}px`
        }}
      />
    ))
  }

  return (
    <div
      style={{ position: "relative", width: "98vw", height: "100vh", justifyItems:'center' }}
      className="pdf-view flex"
    >
      <Document
        file={pdfUrl}
        onLoadSuccess={onDocumentLoadSuccess}
        onContextMenu={e => e.preventDefault()}
      >
        {Array.from(new Array(numPages), (el, index) => (
          <div key={`page_${index + 1}`} style={{ position: "relative" }}>
            <Page 
              pageNumber={index + 1}
              onRenderSuccess={page => { 
                const viewport = page.getViewport({ scale: 1 })
                handleRenderSuccess(page, index + 1, viewport.scale)
              }} 
            />
            {scales[index] &&
              pageHeights[index] &&
              renderHighlights(index + 1, scales[index])}
          </div>
        ))}
      </Document>
    </div>
  )
}

export default PDFViewer3