How to create pickup Distance Calculation miles pricing in WordPress

I am trying to pick up Distance Calculation miles pricing in WordPress but I have not succeeded yet. any help would be appreciated.

Here is my code. but I don’t know what is wrong with my code.

HTML Form
in WordPress where users can input the pickup and destination locations.

function google_maps_distance_calculator_shortcode() {
    ob_start();
    ?>
    <div class="distance-calculator-form">
        <form id="distance-calculator-form">
            <h2>Calculate Distance and Cost</h2>

            <label for="pickup">Pickup Location:</label>
            <input type="text" id="pickup" name="pickup" placeholder="Enter pickup location"><br>

            <label for="destination">Destination Location:</label>
            <input type="text" id="destination" name="destination" placeholder="Enter destination location"><br>

            <p>Distance: <span id="distance">0 km</span></p>
            <p>Total Cost: <span id="total-cost">$0.00</span></p>

            <!-- Button to calculate distance and cost -->
            <button type="button" id="calculate-button">Calculate Distance & Cost</button>
        </form>
    </div>
    <?php
    return ob_get_clean();
}
add_shortcode('google_maps_distance_calculator', 'google_maps_distance_calculator_shortcode');

JavaScript to Calculate Distance Using Google Maps API

document.addEventListener('DOMContentLoaded', function() {
    let map;
    let directionsService;
    let directionsRenderer;

    function initMap() {
        // Initialize the Google Maps objects
        directionsService = new google.maps.DirectionsService();
        directionsRenderer = new google.maps.DirectionsRenderer();
        map = new google.maps.Map(document.getElementById('map'), {
            center: { lat: -34.397, lng: 150.644 },
            zoom: 8
        });
        directionsRenderer.setMap(map);
    }

    function calculateDistance() {
        const pickup = document.getElementById('pickup').value;
        const destination = document.getElementById('destination').value;

        if (pickup && destination) {
            const request = {
                origin: pickup,
                destination: destination,
                travelMode: 'DRIVING'
            };

            directionsService.route(request, function(result, status) {
                if (status == 'OK') {
                    directionsRenderer.setDirections(result);

                    const distance = result.routes[0].legs[0].distance.value / 1000; // distance in km
                    const cost = distance * 2; // Example: $2 per km

                    document.getElementById('distance').textContent = distance.toFixed(2) + ' km';
                    document.getElementById('total-cost').textContent = '$' + cost.toFixed(2);
                } else {
                    alert('Could not calculate distance: ' + status);
                }
            });
        } else {
            alert('Please enter both pickup and destination locations.');
        }
    }

    document.getElementById('calculate-button').addEventListener('click', calculateDistance);

    // Load the map
    initMap();
});

Add Google Maps Script to Your WordPress Site

function enqueue_google_maps_script() {
    wp_enqueue_script('google-maps', 'https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_MAPS_API_KEY&libraries=places', null, null, true);
}
add_action('wp_enqueue_scripts', 'enqueue_google_maps_script');

Add Styling

.distance-calculator-form {
    max-width: 600px;
    margin: 0 auto;
    padding: 20px;
    background-color: #f9f9f9;
    border: 1px solid #ddd;
    border-radius: 8px;
}

.distance-calculator-form label {
    display: block;
    margin-bottom: 8px;
    font-weight: bold;
}

.distance-calculator-form input[type="text"] {
    width: 100%;
    padding: 8px;
    margin-bottom: 10px;
    border: 1px solid #ccc;
    border-radius: 4px;
}

#calculate-button {
    background-color: #007cba;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

#calculate-button:hover {
    background-color: #005f8d;
}

#distance, #total-cost {
    font-weight: bold;
}

How to implement file streaming for an Excel file download in FastAPI to initiate immediate download in browser?

I am building a FastAPI application and need to implement an endpoint that allows users to download an Excel file using streaming. The goal is for the file to start downloading immediately when the user clicks a download button in their browser, similar to how files are downloaded from websites.

Here is my current implementation:


from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import openpyxl
import io
import time

app = FastAPI()

@app.get("/download_excel/")
async def get_attendance_report():
    start_time = time.time()
    
    # Create Excel file in memory
    wb = openpyxl.Workbook()
    ws = wb.active

    headers = ["id", "name", "age", "city", "is_student"]
    ws.append(headers)

    # Sample data
    data = [
        {'id': 1, 'name': 'Alice', 'age': 30, 'city': 'New York', 'is_student': True},
        {'id': 2, 'name': 'Bob', 'age': 25, 'city': 'Los Angeles', 'is_student': False}
    ]
    
    for record in data:
        ws.append([record['id'], record['name'], record['age'], record['city'], record['is_student']])

    log.info(f"File generation time: {time.time() - start_time} seconds")

    def iterfile():
        with io.BytesIO() as byte_stream:
            wb.save(byte_stream)
            byte_stream.seek(0)
            while chunk := byte_stream.read(262144):  # 256KB chunks
                yield chunk

    headers = {
        'Content-Disposition': 'attachment; filename="employee_attendance_report.xlsx"',
        'Transfer-Encoding': 'chunked'
    }
    
    return StreamingResponse(iterfile(), media_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', headers=headers)



Problem:

1.When I click the download button, I receive a status code 200 immediately, but it takes more time for the download process to start.

2.I want the file to be downloaded immediately when the user clicks the download button. The file should appear in the browser’s download manager, showing its name and progress.

What I’ve Tried:
Implemented StreamingResponse to stream the file in chunks.
Set the Content-Disposition header to indicate an attachment and filename.
Questions:
Is the StreamingResponse implementation correct for streaming an Excel file?
Are there any additional headers or configurations required to ensure that the file starts downloading immediately in the browser?
How can I reduce the delay between receiving the status code and the start of the download process?

I have a shopping app component that I only want to show on a particular page. Tried useLocation but the component has dynamic ids

I want to know how I can make my “page” variable in the below code dynamic, so I can properly compare it with the location.pathname variable which will have dynamic page ids.

import { useLocation } from 'react-router-dom';

function AddToCart() {
  function IsItemPage() {
    const page = '/item_page';
    const location = useLocation();
    console.log(location);
    if (location.pathname == page) {
      return true;
    };
  }

  return IsItemPage() && ( 
    <span className='add-to-cart'>
      <button>Add Item</button>
      <button>Cart</button>
    </span>
  );
}

export default AddToCart;

Now each item I open from the home page has a unique id for example: "/item_page/2" and obviously I cannot hard code it. If I provide the absolute path to the “page” variable like "/item_page/1" or something, the component is working as expected but only for that particular item with ‘id: 1’. But I need to be able to achieve this for every item I open from the home page.

So how can I achieve this?

React Native Reanimated interpolateColor issue

I have a simple animated circular progress using react-native-svg and react-native-reanimated.

This is the AnimatedCircle

<Svg height={"90%"} width={"90%"} viewBox="0 0 100 100">
    <AnimatedCircle
        animatedProps={animatedCircleProps}
        cx="50"
        cy="50"
        r="45"
        stroke="rgb(247, 30, 43)"
        strokeWidth="10"
        strokeDasharray={`${radius * Math.PI * 2}`}
        strokeLinecap="round"
    />
</Svg>

This is the animatedCircleProps used in the animatedProps

const animatedCircleProps = useAnimatedProps(() => {
    const interpolatedColor = interpolateColor(
        percentage.value,
        [0, 50, 100],
        [
            "rgb(247, 30, 43)",
            "rgb(255, 248, 48)",
            "rgb(32, 250, 45)",
        ],
    );

    return {
        stroke: interpolatedColor,
        strokeDashoffset: (1 - percentage.value / 100) * circumference,
    };
});

Using the value provided by interpolateColor always gives this error:

 ERROR  ReanimatedError: Exception in HostFunction: java.lang.ClassCastException: java.lang.String cannot be cast to com.facebook.react.bridge.ReadableMap, js engine: reanimated

Is there something I’m missing? Isn’t the value over here also a string? stroke="rgb(247, 30, 43)"

Why doesn’t it work with the animatedCircleProps?

React Native Reanimated useSharedValue() value is unexpected inside useAnimatedGestureHandler()

Here is the code I am using to initialize my shared values:

export default function CardList({ children, players, setPlayers, playerTurnCounter }) {
  const [ready, setReady] = useState(false);

  const offsets = useSharedValue(children.map(() => ({
    order: 0,
    width: 0,
    height: 0,
    x: 0,
    y: 0,
    originalX: 0,
    originalY: 0,
  }));

  if (!ready) {
    return (
      <View style={styles.row}>
        {children.map((child, index) => {
          return (
            <View
              key={child.key}
              onLayout={({
                nativeEvent: { layout: { x, y, width, height } },
              }) => {
               offsets.value[index] = {
                   order: -1,
                   width: width / children + 10,
                   height,
                   x,
                   y,
                   originalX: x,
                   originalY: y,
                );

                runOnUI(() => {
                  'worklet';

                  if (offsets.filter((o) => o.order.value !== -1).length === 0) {
                    runOnJS(setReady)(true);
                  }
                })();
              }}>
              {child}
            </View>
          );
        })}
      </View>
    );
  }
  return (
    <View style={styles.container}>
      {children.map((child, index) => (
        <SortableCard
          key={child.key}
          offsets={offsets}
          index={index}
          players={players}
          setPlayers={setPlayers}
          containerWidth={containerWidth}
          playerTurnCounter={playerTurnCounter}>
          {child}
        </SortableCard>
      ))}
    </View>
  );
} 

And here is my useAnimatedGestureHandler():

/* eslint-disable react/prop-types */
import React, { ReactElement } from 'react';
import { StyleSheet } from 'react-native';
import { PanGestureHandler, PanGestureHandlerGestureEvent } from 'react-native-gesture-handler';
import Animated, {
  runOnJS,
  useAnimatedGestureHandler,
  useAnimatedStyle,
  useDerivedValue,
  useSharedValue,
  withSpring,
} from 'react-native-reanimated';
import { between, useVector } from 'react-native-redash';

import {
  calculateLayout,
  CARD_HEIGHT,
  lastOrder,
  MARGIN_LEFT,
  MARGIN_TOP,
  remove,
  reorder,
  SENTENCE_HEIGHT,
} from '../Layout';

function SortableCard({ offsets, index, children, players, setPlayers, containerWidth }) {
  const offset = offsets.value[index];
  const isGestureActive = useSharedValue(false);
  const isAnimating = useSharedValue(false);
  const translation = useVector();
  const isInBank = useDerivedValue(() => offset.order === -1);
  const onGestureEvent = useAnimatedGestureHandler({
    onStart: (_, ctx) => {
      if (isInBank.value) {
        translation.x.value = offset.originalX - MARGIN_LEFT;
        translation.y.value = offset.originalY + MARGIN_TOP;
      } else {
        translation.x.value = offset.x;
        translation.y.value = offset.y;
      }
      ctx.x = translation.x.value;
      ctx.y = translation.y.value;
      isGestureActive.value = true;
    },
    onActive: ({ translationX, translationY }, ctx) => {
      translation.x.value = ctx.x + translationX;
      translation.y.value = ctx.y + translationY;
     
      if (isInBank.value && translation.y.value < SENTENCE_HEIGHT) {
        offset.order = lastOrder(offsets.value);
        calculateLayout(offsets.value, containerWidth);
      } else if (!isInBank.value && translation.y.value > SENTENCE_HEIGHT) {
        offset.order = -1;
        remove(offsets.value, index);
        calculateLayout(offsets.value, containerWidth);
      }
      for (let i = 0; i < offsets.value.length; i++) {
        const o = offsets.value[i];
        if (i === index && o.order !== -1) {
          continue;
        }
      
        if (
          between(translation.x.value, o.x, o.x + o.width) &&
          between(translation.y.value, o.y - CARD_HEIGHT, o.y + CARD_HEIGHT)
        ) {
          reorder(offsets.value, offset.order, o.order);
          calculateLayout(offsets.value, containerWidth);
          break;
        }
      }
    },
    onEnd: ({ velocityX, velocityY }) => {
      isAnimating.value = true;
      translation.x.value = withSpring(offset.x, { velocity: 0.2 });
      translation.y.value = withSpring(offset.y, { velocity: 0.2 });
      isGestureActive.value = false;
      const tplayers = players;
      if (
        between(translation.x.value, offset.x / 2, offset.x / 2 + offset.width) &&
        between(translation.y.value, offset.y - CARD_HEIGHT, offset.y)
      ) {
     
        let inDeck = false;
        for (let i = 0; i < tplayers[0].subHand.length; i++) {
          if (
            tplayers[0].subHand[i].suite === children.props.item.suite &&
            tplayers[0].subHand[i].value === children.props.item.value
          ) {
            inDeck = true;
          }
        }
        if (!inDeck) {
          tplayers[0].subHand.push(children.props.item);
        }
        runOnJS(setPlayers)(tplayers);
      } else if (
        between(translation.x.value, offset.x, offset.x + offset.width) &&
        between(translation.y.value, offset.y - CARD_HEIGHT, offset.y)
      ) {
        let inDeck = false;
        for (let i = 0; i < tplayers[0].subHand.length; i++) {
          if (
            tplayers[0].subHand[i].suite === children.props.item.suite &&
            tplayers[0].subHand[i].value === children.props.item.value
          ) {
            inDeck = true;
          }
        }
        if (!inDeck) {
          tplayers[0].subHand.push(children.props.item);
        }
        runOnJS(setPlayers)(tplayers);
      } else {
        for (let i = 0; i < tplayers[0].subHand.length; i++) {
          if (
            tplayers[0].subHand[i].suite === children.props.item.suite &&
            tplayers[0].subHand[i].value === children.props.item.value
          ) {
            tplayers[0].subHand.splice(children.props.item, 1);
          }
        }
        runOnJS(setPlayers)(tplayers);
      }
    },
  });
  const translateX = useDerivedValue(() => {
    if (isGestureActive.value) {
      return translation.x.value;
    }
    return withSpring(isInBank.value ? offset.originalX - MARGIN_LEFT : offset.x);
  });
  const translateY = useDerivedValue(() => {
    if (isGestureActive.value) {
      return translation.y.value;
    }
    return withSpring(isInBank.value ? offset.originalY + MARGIN_TOP : offset.y);
  });
  const style = useAnimatedStyle(() => {
    return {
      position: 'absolute',
      top: 0,
      left: 0,
      width: offset.width.value,
      height: CARD_HEIGHT,
      transform: [{ translateX: translateX.value }, { translateY: translateY.value }],
    };
  });
  return (
    <>
      <Animated.View style={style}>
        <PanGestureHandler onGestureEvent={onGestureEvent}>
          <Animated.View style={StyleSheet.absoluteFill}>{children}</Animated.View>
        </PanGestureHandler>
      </Animated.View>
    </>
  );
}

export default SortableCard;

My issue is when I try to access offsets, which is one shared value that stores an array, while inside of useAnimatedGestureHandler, the values are not as expected.

When I put print statements outside of useAnimatedGestureHandler (for example, on the line below ‘offset = offsets.value[index]’) the expected values are printed. Similarly if I console log offsets in the return statement I also see the expected values. But if I try to access offsets inside the gesture handler or if I try to print them, all values are reinitialized to their original values but the initializer doesn’t seem to get called again.

Any help to assist me in understanding what is going on here is greatly appreciated. Thank you!

Having trouble getting autocomplete.js to display results after starting a third word in the search

I have been trying to use an autocomplete library from https://tarekraafat.github.io/autoComplete.js/#/ called autocomplete.js. It is working fine all the way up until I start to add a third word to the query. When I get to the third word, even after one or two characters, I get get “no results found”, but otherwise I get no errors in the console.

If you run the code below, you will see what happens.

Somehow, typing a third word into the search box is causing it to lose the data somewhere between returning the results from the API, and when it gets to resultsList.element. I see no problems with data.src. Can anyone else see any problems with this code?

Here is the code I’m using:

    const autoCompleteJS = new autoComplete({
        selector: "#autoComplete",
        data: {
            src: [
                "Don't Rock The Jukebox - Alan Jackson [CB Karaoke]",
                "Don't Rock The Jukebox - Alan Jackson [NU Karaoke]",
                "Don't Rock The Jukebox - Alan Jackson [DK Karaoke]",
                "Don't Rock The Jukebox - Alan Jackson [SC Karaoke]",
                "Don't Rock The Jukebox - Alan Jackson [P Karaoke]"
            ],
            cache: false // Disable caching for dynamic data
        },
        threshold: 3, // Minimum number of characters before the autocomplete starts
        debounce: 300, // Wait 300ms before fetching the data
        resultsList: {
            element: (list, data) => {
                // Display "No Results" message when no results are found
                if (!data.results.length) {
                    console.log("no results");
                    const message = document.createElement("div");
                    message.setAttribute("class", "no_results");
                    message.innerHTML = `<span>No results found</span>`;
                    list.appendChild(message);
                }
            },
            maxResults: 10, // Maximum number of results to show
            noResults: true
        },
        resultItem: {
            highlight: true,
            element: (item, data) => {
                console.log("data: " + data)
                // Display the result item
                item.innerHTML = `<span>${data.value}</span>`;
            }
        },
        onSelection: (feedback) => {
            const selection = feedback.selection.value;
            document.querySelector("#autoComplete").value = selection;
            console.log("Selected item:", selection);
        }
    });
<link href="https://cdn.jsdelivr.net/npm/@tarekraafat/[email protected]/dist/css/autoComplete.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/@tarekraafat/[email protected]/dist/autoComplete.min.js"></script>
<div class="container mt-5 pt-5 col-md-5">
    <h4>Search Songs</h4>
    <div id="autocomplete" class="autocomplete">
        <input id="autoComplete" type="text" placeholder="Search Karaoke">
        <ul class="autocomplete-result-list"></ul>
    </div>
</div>

EDIT:
I think I figured something out. This library seems to want to search through the results on its own. It doesn’t respect the search results I feed it. As long as the words I type are together in the results, it displays them. Is there a way to keep it from doing its own sorting?

Hiding a parent div based on all child inputs being disabled

I am trying to {display:none} on class=”filter-form__group” only if ALL child Input’s are ‘disabled’.

<div class="filter-form__group">
  <div class="filter-form__group-filter-wrapper" data-filter-type="list">
    <div class="filter-form__list-wrapper">
      <ul class="filter-form__list">
        <li class="filter-item">
          <label data-filter-item="" class="filter-item__content">
            <input type="checkbox" value="Luggage" disabled>
          </label>
        </li>
        <li class="filter-item">
          <label data-filter-item="" class="filter-item__content">
            <input type="checkbox" value="Motorcycle" disabled>
          </label>
        </li>
      </ul>
    </div>
  </div>
</div>

Thanks!

I tried some CSS but they do not seem to work and I believe this may have to be done in JS.

How do i mock MongoDb Connection and Test it

My DB Class to test
I have a DB class where i encapsulate Mongodb methods to test

import mongodb from 'mongodb';
import dotenv from 'dotenv';

// Comfigure dotenv
dotenv.config();

// eslint-disable-next-line no-unused-vars
class DBClient {
  /** 
  * Creates a new DBclient instance.
  */
  constructor() {
    const host = process.env.DB_HOST || 'localhost';
    const port = process.env.DB_PORT || 27017;
    const database = process.env.DB_DATABASE || 'files_manager';

    const dbUri = `mongodb://${host}:${port}/${database}`;
    this.client = new mongodb.MongoClient(dbUri, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    }); 

    this.isClientConnected = false;
    this.client.connect((err) => {
      if (err) {
        console.error('Error encounted while connecting to MongoDB', err);
      } else {
        this.isClientConnected = true;
        console.log('Connected to MongoDB');
      }   
    }); 
  }

  /** 
  * check the status of the connection to MongoDB
  * @returns {boolean}
  */
  isAlive() {
    return this.isClientConnected;
  }
}

const dbClient = new DBClient();
module.exports = dbClient;

My Test File
My intention is to mock the connection to db then test

const { expect } = require('chai');
const sinon = require('sinon');
const mongodb = require('mongodb');
const dbClient = require('../utils/db');

describe('DBClient', function() {
  afterEach(function() {
    // Automatically restore all stubs after each test
    sinon.restore();
  }); 

  it('should initialize and connect successfully', function(done) {
    const connectStub = sinon.stub(mongodb.MongoClient.prototype, 'connect').callsFake(function(cb) {
      cb(null); // No Error
    });  
    // Wait for the next tick to allow the callback to execute
    process.nextTick(() => {
      expect(dbClient.isAlive()).to.be.true;
      expect(connectStub.calledOnce).to.be.true;
      done();
    }); 
  }); 
  
  it('should fail to connect and isAlive returns false', function(done) {
    // Stub the connect method to simulate a connection failure
    const connectStub = sinon.stub(mongodb.MongoClient.prototype, 'connect').callsFake(function(cb) {
      cb(new Error('Failed to connect')); 
    }); 

    process.nextTick(() => {
      expect(dbClient.isAlive()).to.be.false;
      expect(connectStub.calledOnce).to.be.true();
      done();
    }); 
  }); 
});

When i run the test
The two test cases are falling with the following error.

  DBClient
    1) should initialize and connect successfully
    2) should fail to connect and isAlive returns false


  0 passing (20ms)
  2 failing

  1) DBClient
       should initialize and connect successfully:

      Uncaught AssertionError: expected false to be true
      + expected - actual

      -false
      +true
      
      at /root/alx-files_manager/test/connectToMongoDb.test.js:18:39
      at processTicksAndRejections (node:internal/process/task_queues:77:11)

  2) DBClient
       should fail to connect and isAlive returns false:

      Uncaught AssertionError: expected false to be true
      + expected - actual

      -false
      +true
      
      at /root/alx-files_manager/test/connectToMongoDb.test.js:32:43
      at processTicksAndRejections (node:internal/process/task_queues:77:11)

I suspect my issue is starting when I stub the connection to the DB. Please assist

JavaScript Discord Error, TypeError: client.handleCommands is not a function

Hello guys so I’m experiencing this problem with Discord bot making in JavaScript.
I’m following a tutorial from Fusion Terror.
The error I’m experiencing is that it’s saying handleCommands.js is not a function, it works for him but not for me.

Full error:

~@~: workspace/project_name$ node .
/home/username/workspace/project_name/src/bot.js:26
client.handleCommands();
       ^

TypeError: client.handleCommands is not a function
    at Object <anonymous> (/home/username/workspace/project_name/src/bot.js:6:8)
    at Module._compile (node:internal/modules/cjs/loader:1469:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1548:10)
    at Module.load (node:internal/modules/cjs/loader:1288:32)
    at Module._load (node:internal/modules/cjs/loader:1104:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:174:12)
    at node:internal/main/run_main_module:28:49

Node.js v20.17.0

All the files and folders:
file and folder organization

bot.js code:

require("dotenv").config();

const { Client, Collection, GatewayIntentBits } = require("discord.js");
const client = new Client({
  intents:
    (GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent),
});
const { token } = process.env;
const fs = require("fs");

client.commands = new Collection();
client.commandArary = [];

const functionFolders = fs.readdirSync(`./src/functions`);
for (const folder of functionFolders) {
  const functionFiles = fs
    .readdirSync(`./src/functions/${folder}`)
    .filter((file) => file.endsWith(`.js`));
  for (const file of functionFiles)
    require(`./functions/${folder}/${file}`)(client);
}

client.handleEvents();
client.handleCommands();

client.login(token);

handleCommand.js code:

const fs = require("fs");

module.exports = (client) => {
  client.commandHandler = async () => {
    const commandsFolder = fs.readdirSync(`./src/commands`);
    for (const folder of commandsFolder) {
      const commandFiles = fs
        .readdirSync(`./src/commands/${folder}`)
        .filter((file) => file.endsWith(`.js`));

      const { commands, commandsArray } = client;
      for (const file of commandFiles) {
        const command = require(`../commands/${folder}/${file}`);
        commands.set(command.data.name, command);
        commandsArray.push(command.data.toJSON());
        console.log(
          `Command ${command.data.name} has been regtistered through the command handler succesfully.`
        );
      }
    }
  };
};

Thanks in advance!

Well I tried re-writing the code which at the moment I thought would help, whilst it didn’t and the same error occured

useQueries dependent on another Query, whose data is with 3 levels depth

I am facing a situation where I will first use a useQuery to fetch an object, which contains multiple URLs three levels deep. And then, I’ll use a useQueries to fetch all those URLs. And example given Dependent Queries cannot handle this situation.

For example:

// Get the users ids
const { data: userIds } = useQuery({
  queryKey: ['users'],
  queryFn: getUsersData
})

const usersMessages = useQueries({
  queries: userIds ?
     userIds.map(id => {
        return {
          queryKey: ['messages', id],
          queryFn: () => getMessagesByUsers(id),
        };
      })
  : [],
})

The above code works if userIds is like:
[ url1, url2, url3, url4 ] .
However, in my case, the userIds has the following structure:

[
  {'name':'A', 'id': [url1, url2]}, 
  {'name':'B', 'id': [url3, url4]}
]

and my objective is to fetch from all URLs.

I can’t change the first query using “select” to change the format of the returned data because I am collaborating with others, and changing that would incur many other refactors.

I tried to first get userIds, and then decompose it to form a new array that only contains all the URLs, give this new array to the second useQueries and meanwhile set dependency on !isLoading of the first query, which does not work. The code enters in to a loop and throw an error “Rendered more hooks than during the previous render”.

How do i make my Javascript/html form processing print out?

Im writing a peice of code for a school project, I took code from a form i wrote for myself last year (that worked) and just wrewrote the questions and variable names. But now the processed data is not printing and i get this error :

Uncaught TypeError: Cannot set properties of null (setting 'innerHTML')
    at showQuestions (script.js:139:29)
    at generateQuiz (script.js:204:3)
    at window.onload (script.js:6:2)

here is the code for my form page:

<!DOCTYPE HTML >
<html>
   <head>
      <title>Review!</title>
      <link rel= "stylesheet" type= "text/css" href= "style.css">
      <!--Links to the stylesheet-->
      <link rel="icon" type="image/x-icon" href="coolfavicon.png">
      <!--favicon, puts an icon on the head instead of the default-->
      <script src="script.js"></script>
      <meta charset="UTF-8">
   </head>
   <body>
      <div class="navbar">
         <a href="index.htm">Home</a>
         <a href="info.htm">Information</a> <!--navigaion bar to access all pages-->
         <a href="quiz.htm">Quiz!</a>
         <div class="dropdown">
            <button class="dropbtn">
               More information ▼<!--dropdown tag for different information pages-->
            </button>
            <div class="dropdown-content">
               <a href="history.htm">History of cars</a>
               <a href="Records.htm">Car world records</a>
               <a href="Purchase.htm">How to buy a car</a> 
            </div>
         </div>
         <div class ="countdown">
            <p>Coundown to Auckland Christmas car meet: <span id="demo" style="align:right"      ></span></p>
            <!--script countdown timer-->
         </div>
      </div>
      <div class="hero-image-info">
         <div class="hero-text">
           <u>Please fill out this form:</u>
           <br>
           <div class="funnydiv">
            <u>Rutherford College e-sports signup</u>
            <br>
            <br>
            </div>
            <form method="get" action   ="process.htm">
            <u><label for ="name">What is your name?</label><br></u>
            <input type="text" id="name" name="name" required placeholder="Name"><br><!--text input tags for Name-->
            <br>
            <u><label for ="email">What is your email adress?</label><br></u>
            <input type="text" size="20" id="email" name="email" required placeholder="email" ><br><!--text input tags for Email-->
            <br>
            <u><label for="outof5">Out of 5, How would you rate this website overall?</label><br></u>
            <br>
            <input type="radio" id="1" name="outof5" required value="1"> <span>1</span> 
            <br>
            <input type="radio" id="2" name="outof5" required value="2"> <span>2</span> <!--input tags for review-->
            <br>
            <input type="radio" id="3" name="outof5" required value="3"> <span>3</span> 
            <br>
            <input type="radio" id="4" name="outof5" required value="4"> <span>4</span> 
            <br>
            <input type="radio" id="5" name="outof5" required value="5"> <span>5</span> 
            <br>
            <u><label for="page">Personally, what was your favorite page on our website?</label><br></u>
            <br>
            <input type="radio" id="Home" name="page" required value="Home"><span>Home</span> 
            <br>
            <input type="radio" id="Information" name="page" required value="Information"><span>Information</span> 
            <br>
            <input type="radio" id="Records" name="page" required value="Records"><span>Records</span> 
            <br>
            <input type="radio" id="History" name="page" required value="History"><span>History</span><!--input tags for year at school-->
            <br>
            <input type="radio" id="Quiz" name="page" required value="Quiz"><span>Quiz</span>
            <br>
            <input type="radio" id="Purchasing" name="page" required value="Purchasing"><span>Purchasing</span>
            <br>
            <br>
            <u><label for="score">What did you score on our quiz?</label><br></u>
            <br>
            <input type="radio" id="0-4 (extremely low)" name="score" value="0-4 (extremely low)"> <span>0-4 (extremely low)</span>
            <br>
            <input type="radio" id="5-7 (low)" name="score" required value="5-7 (low)"> <span>5-7 (low)</span>
            <br>
            <input type="radio" id="8-10(medium)" name="score" required value="8-10(medium)"> <span>8-10(medium)</span><!--input tags for experience in said game-->
            <br>
            <input type="radio" id="11-13(high)" name="score" required value="11-13(high)"> <span>11-13(high)</span>
            <br>
            <input type="radio" id="14-15(very high)" name="score" required value="14-15(very high)"> <span>14-15(very high)</span>
            <br>
            <br>
            <input type="submit" name="submit" value="Submit" class="button"/>
            </form>
            
            <a class = "button" onclick="topFunction()" id="totopbutton" title="Go to top">Back to top</a> 
         </div>
         <div class ="footer">
            <p><a href="privacy.htm">‏‏‎ ‎‎‎‎‎‎‎Privacy Policy</a>‏‏‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‎Phone:0800 838 828‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎Email:[email protected]</p>         </div>
         <br>
      </div>
   </body>
</html> 

Here is the processing page:

<!DOCTYPE HTML >
<html>
   <head>
      <title>Information</title>
      <link rel= "stylesheet" type= "text/css" href= "style.css">
      <!--Links to the stylesheet-->
      <link rel="icon" type="image/x-icon" href="coolfavicon.png">
      <!--favicon, puts an icon on the head instead of the default-->
      <script src="script.js"></script>
      <meta charset="UTF-8">
   </head>
   <body>
      <div class="navbar">
         <a href="index.htm">Home</a>
         <a href="info.htm">Information</a> <!--navigaion bar to access all pages-->
         <a href="quiz.htm">Quiz!</a>
         <div class="dropdown">
            <button class="dropbtn">
               More information ▼<!--dropdown tag for different information pages-->
            </button>
            <div class="dropdown-content">
               <a href="history.htm">History of cars</a>
               <a href="Records.htm">Car world records</a>
               <a href="Purchase.htm">How to buy a car</a> 
            </div>
         </div>
         <div class ="countdown">
            <p>Coundown to Auckland Christmas car meet: <span id="demo" style="align:right"      ></span></p>
            <!--script countdown timer-->
         </div>
      </div>
      <div class="hero-image-index">
         <div class="hero-text">
                <br><br>
         <br><br><br><br>
                </p>processed data:</p>
                Your Name: <span id="name"></span>
                <br>
                Your email: <span id="email"></span>   <!--these lines print the variables that would have been entered on the previous form page-->
                <br>
                Website rating out of 5: <span id="outof5"></span>
                <br>
                Favorite page: <span id="page"></span>
                <br>
                Quiz score: <span id="score"></span>
                <br>
            <!--basic content-->
            <p>We hope you enjoy playing with us!</p>
            <a class = "button" onclick="topFunction()" id="totopbutton" title="Go to top">Back to top</a> 
         </div>
         <br>
         <br><br>
         <div class ="footer">
            <p><a href="privacy.htm">‏‏‎ ‎‎‎‎‎‎‎Privacy Policy</a>‏‏‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‎Phone:0800 838 828‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎Email:[email protected]</p>         </div>
         <br>
      </div>
   </body>
</html> 

And here is the javascript:

window.onload = function(){
    var quizContainer = document.getElementById('quiz');
    var resultsContainer = document.getElementById('results');
    var submitButton = document.getElementById('submit');

    generateQuiz(myQuestions, quizContainer, resultsContainer, submitButton);
    
    url = window.location.href;
    console.log(url)
    if( url.indexOf("privacy")> 0){
        showSlides();
    } 
    if(url.indexOf("process")> 0){
        processForm();
    }
    console.log(url)
    //helps to run javascript where it is needed (slides and processing)
}

//PROCESSING AND form

function processForm(){
    //getname
    value = get_url_parameter("name");
    document.getElementById("name").innerHTML = value;
    //getemail
    value = get_url_parameter("email");
    document.getElementById("email").innerHTML = value;
    //getoutof5
    value = get_url_parameter("outof5");
    document.getElementById("outof5").innerHTML = value;
    //getpage
    value = get_url_parameter("page");
    document.getElementById("page").innerHTML = value;
    //getscore
    value = get_url_parameter("score");
    document.getElementById("score").innerHTML = value;
    
}
var url_string = window.location.href;

function get_url_parameter(parameter) {
    //get the passed url string
    var url_string = window.location.href;
    //split at the question mark in the url vor values passed
    var all_parts = url_string.split("?");
    //split the second part into the passed perameters
    var passed_values = all_parts[1].split("&");
    //return array for radio buttons
    var return_array = []
    //cycle through all passed values
    for (i=0;i<passed_values.length;i++){
        section_parts = passed_values[i].split("=")
        //match the first part of the url with the passed perimiter
        if (parameter == section_parts[0]){
            //put it into our array
            return_array.push(section_parts[1])
        }
    }
    //return array
    return return_array;
}

Ive checked all of the variables, and it looks exactly the same as my working code (apart from variable names) and im very confused as to why it is not printing out the processed information.

This is what i see on the processing page

This is the working view from last year

Trouble setting up eslint_d in neovim for Javascript projects

So I’ve had my lsp setup with neovim for a minute now, but I’ve just started working on a javascript project and I realize I have no idea how to setup eslint_d. I’ve scoured the internet for answers but I haven’t really seen anything that’s a “eslint for dummies” type of deal.

I use Mason along with nvim-lspconfig and nvim-lint mainly to do my language server stuff and linting.

What I’m confused about is, if I have eslint_d installed through Mason, do I still need to run an ‘npm init’ command in my directory? Or ‘npm i eslint’ or something like that? I had it linting properly before, except for the fact that it wouldn’t read custom types. I have a types folder in my working directory that’s symlinked to a types folder outside, and in my tsconfig.json I have “./types” in my typeRoots, yet it says these types are undefined and undeclared. Listing them as readonly globals does nothing as well.

Could someone just give me the step by step on how I’m supposed to set up projects using eslint_d through Mason?

is there a way to add the video the static page in tauri application?

when i try to load a video from the video tag in html it works in the dev but not in build in tauri app
enter image description here
this is the image of the file tree
now the code that load the video

<video
    src="./assets/video/textify.mp4"
    id="video"
    muted
    autoplay
></video>

when i try google it its says that i need to add the location of the video to the resource in the tauri.config.json i did that but it did not work

How to disable the “Upload Image” button in unlayer using vue-email-editor?

I’m using vue-email-editor (a Vue wrapper for unlayer) to integrate an email editor in my Vue 3 project. Everything works fine, but I want to disable the “Upload Image” button that allows users to upload their own images. I’ve been unable to find a solution in the documentation or source code.

Here’s my current setup:
I’ve initialized the editor with the following configuration:

<template>
  <div>
    <EmailEditor
      ref="emailEditor"
      :appearance="emailEditorConfits.appearance"
      :options="emailEditorConfits.options"
      :tools="emailEditorConfits.tools"
      :project-id="emailEditorConfits.projectId"
      @ready="editorLoaded"
    />
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { EmailEditor } from 'vue-email-editor';

const emailEditor = ref(null);

const emailEditorConfits = {
  appearance: {
    panels: {
      tools: { dock: 'right' }
    }
  },
  options: {
    features: {
      userUploads: false,
    },
    imageUploader: {
      shouldRender: {
        dropzone: false,         // Disable dropzone for image uploads
        uploadButton: false,     // Disable the upload button
        userUploads: true,       // Keep user uploaded images visible
        stockImages: true,       // Enable stock images
        moreImages: true,        // Enable more images
      },
    },
  },
  tools: {},
  projectId: <abc-123>,
};

const editorLoaded = () => {
  emailEditor.value.registerProvider('userUploads', function (params, done) {
    const images = [
      {
        id: Date.now(),
        location: 'https://picsum.photos/id/1/500',
        width: 500,
        height: 500,
        contentType: 'image/png',
        source: 'user'
      }
    ];
    done(images);
  });
};
</script>

What I’ve Tried:

  1. I’ve attempted to disable the “Upload Image” button by setting shouldRender.uploadButton and shouldRender.dropzone to false within the imageUploader configuration, but the button and dropzone are still visible.
  2. I’ve looked through the unlayer documentation and vue-email-editor issues but haven’t found a way to specifically disable the “Upload Image” button.
  3. I’ve checked the node_modules code of ImageUploader, and the relevant part seems to allow customization through shouldRender, but it doesn’t seem to work as expected.

Question:

How can I disable the “Upload Image” button in unlayer when using the vue-email-editor package? Is there any way to fully hide this button or the entire user-upload option?

I appreciate any guidance or examples on how to achieve this!

Add dynamic styles to AG Grid row groups

I’m having trouble adding dynamic styles to row groups on an AG Grid table because I need each row group to have its own custom background color in hex that comes from an API.

I’ve tried using AG Grid’s autoGroupColumnDef with cellStyle, but since AG Grid only stores the value that will be displayed, I can’t access it.

To illustrate what I want, I made a drawing.
Image

Here is my code:

var levels = "";

if (data != null && data != undefined && data.d != '[]') {
    levels = JSON.parse(data.d)[0].levels;
}

var columnDefs = [{
        headerName: "CT1",
        field: "category1",
        rowGroup: true,
        filter: true,
        rowGroupIndex: 1,
        hide: true
    },
    {
        headerName: "CT2",
        field: "category2",
        rowGroup: true,
        filter: true,
        rowGroupIndex: 2,
        hide: true
    },
    {
        headerName: "CT3",
        field: "category3",
        rowGroup: true,
        filter: true,
        rowGroupIndex: 3,
        hide: true
    },
    {
        headerName: "CT4",
        field: "category4",
        rowGroup: true,
        filter: true,
        rowGroupIndex: 4,
        hide: true
    },
    {
        headerName: "CT5",
        field: "category5",
        rowGroup: true,
        filter: true,
        rowGroupIndex: 5,
        hide: true
    },
    {
        headerName: "CT6",
        field: "category6",
        rowGroup: true,
        filter: true,
        rowGroupIndex: 6,
        hide: true
    },
    {
        headerName: "CT7",
        field: "category7",
        rowGroup: true,
        filter: true,
        rowGroupIndex: 7,
        hide: true
    },
    {
        headerName: "CT8",
        field: "category8",
        rowGroup: true,
        filter: true,
        rowGroupIndex: 8,
        hide: true
    },
    {
        headerName: "CT9",
        field: "category9",
        rowGroup: true,
        filter: true,
        rowGroupIndex: 9,
        hide: true
    },
    {
        headerName: "CT10",
        field: "category10",
        rowGroup: true,
        filter: true,
        rowGroupIndex: 10,
        hide: true
    },
    {
        headerName: "C",
        field: "descriptionC",
        rowGroup: true,
        filter: true,
        rowGroupIndex: 11,
        hide: true
    },
    {
        headerName: "C",
        field: "descriptionC",
        rowGroup: true,
        filter: true,
        hide: true
    },
    {
        headerName: "color1",
        field: "color1",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "color2",
        field: "color2",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "color3",
        field: "color3",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "color4",
        field: "color4",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "color4",
        field: "color5",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "color6",
        field: "color6",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "color7",
        field: "color7",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "color8",
        field: "color8",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "color9",
        field: "color9",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "color10",
        field: "color10",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "ID1",
        field: "idCategory1",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "ID2",
        field: "idCategory2",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "ID3",
        field: "idCategory3",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "ID4",
        field: "idCategory4",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "ID4",
        field: "idCategory5",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "ID6",
        field: "idCategory6",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "ID7",
        field: "idCategory7",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "ID8",
        field: "idCategory8",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "ID9",
        field: "idCategory9",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "ID10",
        field: "idCategory10",
        aggFunc: "avg",
        hide: true
    },
    {
        headerName: "",
        field: "edit",
        width: 50,
        cellClass: 'text-center',
        sortable: true,
        hide: masterOnlyView == "1",
        cellClassRules: {
            "gridIconEdit": function(params) {
                return params.node.key != null && params.node.field != "descricaoCIP"
            },
            "text-center": function(params) {
                return params.node.key == null || params.node.field == "descricaoCIP"
            }
        }
    }
];
var obj = JSON.parse(data.d);

var gridOptions = {
    columnDefs: columnDefs,
    singleClickEdit: true,
    stopEditingWhenCellsLoseFocus: true,
    rowSelection: 'multiple',
    groupDefaultExpanded: levels - 1,
    animateRows: true,
    rowData: obj,
    defaultColDef: {
        filter: true,
    },
    autoGroupColumnDef: {
        pinned: 'left',
        minWidth: 1000,
        headerName: lblColunaDescricao,
        cellStyle: (cell) => {
            if (cell.node.field != "descricaoCIP") {
                return {
                    backgroundColor: 'green'
                }
            }
        },
        cellClassRules: {
            "cell-blue": function(params) {
                return params.node.field == "descricaoCIP"
            },
            "total-cell-left-no-bg": function(params) {
                return params.node.field != "descricaoCIP"
            }
        }
    },
};
var eGridDiv = document.querySelector('#myGrid');
eGridDiv.innerHTML = "";

let gridElement = new agGrid.Grid(eGridDiv, gridOptions);
fnGlobalSetGridOptions(gridElement, {
    gridOptions
});

The API return has a structure like this for each value, and then it is grouped by AG Grid:

{
    category1: "1. CATEG",
    category2: "1.1. SUB CATEG",
    category3: "1.1.1. SUB SUB CATEG FV",
    category4: null,
    category5: null,
    category6: null,
    category7: null,
    category8: null,
    category9: null,
    category10: null,
    codeC: "FV01.01.02",
    color1: "#1cd1d4",
    color2: "#e83030",
    color3: "#FFFFFF",
    color4: null,
    color5: null,
    color6: null,
    color7: null,
    color8: null,
    color9: null,
    color10: null,
    descriptionC: "FV01.01.02",
    idC: 13161,
    idCategory1: 49,
    idCategory2: 50,
    idCategory3: 52,
    idCategory4: 0,
    idCategory5: 0,
    idCategory6: 0,
    idCategory7: 0,
    idCategory8: 0,
    idCategory9: 0,
    idCategory10: 0,
    levels: 3
}

Can anyone help?