Vue 2 draggable not reactive when v-model value is an iterable of parent tag

I am using Vue 2 with Vuex. The received object is first sorted into separate sub-objects based on classCategory value.
Does it not work because the v-model value in draggable is a key from parent tag object?

<div class="class-draggable__group" v-for="group in groupedClasses" :key="group.categoryLocalised">
                    <label class="class-draggable__label__category">{{ group.categoryLocalised }}</label>
                    <draggable v-model="group.classes"
                        :options="{ group: 'classes', dragClass: 'drag', ghostClass: 'ghost' }">
                        <div v-for="classItem in group.classes" :key="classItem.class" class="class-draggable__draggable__item">
                            <div class="d-flex align-items-center">
                                <svg-icon name="drag" class="mr-8 move item"></svg-icon>
                                <div>{{ classItem.classLocalised }}</div>
                            </div>
                            <div class="class-info d-flex align-items-center">
                                <checkbox class="class-draggable__draggable__item__checkbox" :view="1"
                                    v-model="classItem.enabled" @select="toggleClassEnabledValue(classItem.class, $event)" />
                                <div class="icon-wrapper">
                                    <svg-icon v-if="classItem.taximeterEnabled" name="taximeterIcon"></svg-icon>
                                </div>
                                <div class="icon-wrapper">
                                    <svg-icon v-if="classItem.haggleEnabled" name="haggleIcon"></svg-icon>
                                </div>
                                <btn :content="{ icon: 'edit' }" class="class-draggable__draggable__item__button mr-8"
                                    round="circle" @click="editClassHandler(classItem.class)" />
                            </div>
                        </div>
                    </draggable>
                </div>
groupedClasses() {
            const groups = {};
            this.zoneInfoClasses.forEach(classItem => {
                if (!groups[classItem.categoryLocalised]) {
                    groups[classItem.categoryLocalised] = [];
                }
                groups[classItem.categoryLocalised].push(classItem);
            });
            return Object.keys(groups).map(categoryLocalised => ({
                categoryLocalised,
                classes: groups[categoryLocalised],
            }));
        },

here’s the zoneInfoClasses object:


0   Object { class: "delivery", classLocalised: "Доставка", categoryLocalised: "Доставка", … }
class   "delivery"
classLocalised  "Доставка"
categoryLocalised   "Доставка"
enabled true
taximeterEnabled    false
haggleEnabled   false
1   Object { class: "comfort", classLocalised: "Комфорт", categoryLocalised: "Такси", … }
class   "comfort"
classLocalised  "Комфорт"
categoryLocalised   "Такси"
enabled false
taximeterEnabled    false
haggleEnabled   false
2   Object { class: "cargo", classLocalised: "ГрузоТакси", categoryLocalised: "Доставка", … }
class   "cargo"
classLocalised  "ГрузоТакси"
categoryLocalised   "Доставка"
enabled false
taximeterEnabled    false
haggleEnabled   false
3   Object { class: "business", classLocalised: "Бизнес", categoryLocalised: "Такси", … }
class   "business"
classLocalised  "Бизнес"
categoryLocalised   "Такси"
enabled false
taximeterEnabled    false
haggleEnabled   false

Dragging functionality is working fully visually only. When I release the dragged item all items are reset to their starting position.

document.querySelector is returning null for a very simple beginner problem. I have no idea why [duplicate]

html is basically boiler plate

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="script.js"></script>
  </head>
  <body>
    <input id="text-input" required placeholder="Please input a value" />
    <button id="check-btn"></button>
    <div id="result"></div>
  </body>
</html>

js

const textInput = document.querySelector("input");

console.log(textInput);

returns null. Ive watched youtube videos and do exactly what they did and console will log the input element. Ive also tried using .text-input and #text-input

IF Else statement not properly worked in setInterval() function while creating count-down timer

Even after adding if else statment inside setInterval() function to clear the interval once my time variable reaches 0, the setInterval() is still running with negative time value.

Please specify what the problem is and provide some solution for the same.

Here is my code for count-down timer component:

import { useEffect, useState, useRef } from "react";

export const Timer = () => {
  const [time, setTime] = useState(10000);
  const [pause, setPause] = useState(false);
  let timerRef = useRef(null);

  useEffect(() => {  
    startTimer();
  
    return () => clearInterval(timerRef.current);
  }, []);

  const stopTimer = () => {
    clearInterval(timerRef.current);
    setPause(true);
  };

  const startTimer = () => {
    setPause(false);
    timerRef.current = setInterval(() => {
      if (time <= 0) {
        clearInterval(timerRef.current);
        setPause(true);
      }
      else{
        setTime((prevTime) => prevTime - 1000);
      }
    }, 1000);

  };

  const getFormattedText = (time) => {
    const SECONDS = 1000;
    const MINUTES = 60 * SECONDS;
    const HOURS = 60 * MINUTES;
    const DAYS = 24 * HOURS;

    const days = Math.floor(time / DAYS);
    const hours = Math.floor((time % DAYS) / HOURS);
    const minutes = Math.floor((time % HOURS) / MINUTES);
    const seconds = Math.floor((time % MINUTES) / SECONDS);

    return (
      <div className="countdown-timer">
        {days < 10 ? `0${days}` : days} : {hours < 10 ? `0${hours}` : hours} :{" "}
        {minutes < 10 ? `0${minutes}` : minutes} :{" "}
        {seconds < 10 ? `0${seconds}` : seconds}
      </div>
    );
  };
  return (
    <>
      {getFormattedText(time)}
      <div>
        <button onClick={pause ? startTimer : stopTimer}>
          {!pause ? "Stop" : "Start"} Timer
        </button>
      </div>
    </>
  );
};

export default Timer;

Here is the output after 0 second:

This is the link for Output’s image

How to use ProxyAgent with http_proxy and no_proxy environment variables

Im looking into how to use ProxyAgent to enable the functionality of https_proxy and http_proxy environment variables but I cant quite make sense of the documentation (https://www.npmjs.com/package/proxy-agent/v/6.4.0).
If I instantiate a new ProxyAgent, how do I pass in the uri? Would it be something like

new ProxyAgent({uri:process.env.http_proxy})

The documentation says that ProxyAgent will take an options argument of type ProxyAgentOptions, but im not sure what the ProxyAgentOptions should look like and if it even accepts a uri parameter.

Also how will ProxyAgent know to use http_proxy or the https_proxy variable? Is that logic that ProxyAgent handles or would I have to implement that logic myself? Same for a no_proxy list; Is that something that ProxyAgent can handle? Or would I have to implement no_proxy logic myself. Asking because I couldnt find documentation explaining this.

Unable to preventDefault inside passive event listener invocation using Quasar Framework

I am using the Quasar Framework on a Vue3 application.

I have “successfully” integrated the <q-slider /> component. However, upon panning the knob on the component, the following message gets logged on the console.

Unable to preventDefault inside passive event listener invocation

Efforts to resolve the issue have pointed me towards the browser with a common css solution being style="touch-action: pan-x;" but this does not work for me.

I have tested this on;

  • Chrome: issue exists,
  • Edge: issue exists,
  • Firefox: issue exists
  • Safari: issue DOES NOT exist.

My Quasar versions are:

  • “@quasar/extras”: “^1.16.9”,
  • “quasar”: “^2.15.1”,
  • “@quasar/app-vite”: “^1.8.0”,

Typahead Search – why is my React State one step behind?

I’m building a typahead search that listens to the state of the input and renders a list of search results that include the input. But my function checkTypaheadMatches, which sets the state for the results that match the input state, is one step behind. For some reason, in this function, the input state is one step behind.

However, if I console log the input state OUTSIDE of the function, it is not behind. I’m confused because I thought I had my onChange function setup currently on my input. What is wrong? How can I fix it?

Here is my App.jsx (it renders the Header component, which renders my SearchBar component.)

import { useState } from 'react'
import { Outlet, useNavigate } from "react-router-dom"
import Header from "./components/Header"

const App = () => {
  const navigate = useNavigate()

  const validRecipTypes = ["medical doctor", "doctor of osteopathy", "doctor of podiatric medicine", "physician assistant", "nurse practitioner", "certified registered nurse anesthetist", "doctor of dentistry"]

  const [recipTypeQ, setRecipTypeQ] = useState("")
  const [typaheadMatches, setTypaheadMatches] = useState(validRecipTypes)
  const [searchResults, setSearchResults] = useState([])

  const checkTypaheadMatches = () => {
    let matches = []
    for (const recipient_type of validRecipTypes) {
        if (recipient_type.includes(recipTypeQ.toLowerCase())) {
            matches.push(recipient_type)
        }
    }

    console.log("Am I fixed yet?: ", recipTypeQ) // <-- this is one step behind!

    setTypaheadMatches(matches)
  }

  const onRecipTypeQChange = (e) => {
    setRecipTypeQ(e.target.value, checkTypaheadMatches()) // <-- did I do this right?
  }

  const handleSearch = (e) => {
    // search function
  }

  return <>
    <div className="App w-screen p-8">
      <Header 
        onRecipTypeQChange={onRecipTypeQChange} 
        handleSearch={handleSearch} 
        recipTypeQ={recipTypeQ}
        typaheadMatches={typaheadMatches}
        setTypaheadMatches={setTypaheadMatches}
        />
      <Outlet context={[
        searchResults, setSearchResults,
        validRecipTypes
      ]} />
    </div>
  </>
}

export default App

My SearchBar.jsx

import TypaheadMatchesDisplay from "./TypaheadMatchesDisplay";

const SearchBar = ({onRecipTypeQChange, handleSearch, typaheadMatches}) => {
    return <div className="flex items-center gap-6 px-4 border-2 border-green-500 relative">
        <label htmlFor="search_form" className="text-lg font-medium">Search:</label>

        <form data-test="search-form" onSubmit={handleSearch} method="GET" id="search_form">

            <input onChange={onRecipTypeQChange} type="text" id="recipTypeQ" name="recipTypeQ" required mindocLength="1" placeholder="search by recipient type..."/>

            <TypaheadMatchesDisplay typaheadMatches={typaheadMatches}/>

            <button data-test="submit-button" type="submit" form="search_form" value="Submit">Submit</button>
        </form>
    </div>
}

export default SearchBar

What is the problem in the Trace function in this project?

I am doing this project on Oracles, here are the specifications of the project:
Objective: developing an oracle to test (possibly broken) solutions to the Stable Matching Problem.
Specifications: Only working on Part B for now:
An oracle is a function that answers a yes or no question. In this case, we are writing an oracle to decide if the supplied function correctly solves the Stable Matching Problem.

Our oracle’s job is to generate and feed test inputs to a given “solution” (possibly incorrect) then test the correctness of the output.
(Anyone who doesn’t know can read over the Stable Matching Problem on wikipedia)

Companies and Candidates
For this assignment, our groups will consist of companies and candidates. Each company has a ranking of all candidates, in order of preference. And each candidate has a ranking of all companies. Preference lists will be represented as arrays, with the first preference at index 0 and the last preference at index n-1

Companies and candidates are each assigned a number between 0 and n−1. Thus, a two-dimensional array can represent the preferences of a single group:

// n = 3 = There are three companies. = There are three candidates.
[
  [0, 1, 2], // Index 0: Company 0's preference list
  [1, 2, 0], // Index 1: Company 1's preference list
  [0, 2, 1], // Index 2: Company 2's preference list
];

Each element of this 2D array is a preference list. Each element of a preference list is a candidate’s number. Company 0’s first preference is Candidate 0, then Candidate 1, then lastly Candidate 2. Candidate preference lists are structured the same way. However, each number corresponds to a company rather than a candidate.

Inside of stableMatching.d.ts, we can find the following type definitions:

interface Hire {
  company: number;
  candidate: number;
}

type StableMatcher = (companies: number[][], candidates: number[][]) => Hire[];

A Hire is an object with two fields that represents a matching between a company and candidate. A StableMatcher is a function that takes in two 2D arrays of numbers, specifically the preferences of the companies and candidates, and returns an array of Hire objects (Hire[]).

Along with these type definitions, there are two relevant exported members (functions), both of type StableMatcher. They are: STABLE_MATCHING_SOLUTION_1 and FLAWED_STABLE_MATCHING_SOLUTION_1. They are used inside the provided tests (oracle.test.ts) to check against our solution. Their implementations are obfuscated inside of stableMatching.js.

ACTUAL PROGRAMMING TASK:

write an oracle that determines if a function follows the specified algorithm:

Algorithm: We assume the following non-standard variant: At any step, any unmatched company or candidate may propose. Every party always proposes to the next potential partner on their preference list, starting with the top choice. Proposals are not repeated. Any unmatched party that receives a proposal accepts unconditionally. If the receiving party is already matched, but they receive a better offer (higher in their preference list), they accept, and their current partner becomes unmatched; otherwise, the offer is rejected. The algorithm ends when all parties are either matched or have made offers to the entire preference list. The algorithm is under-specified/nondeterministic: it doesn’t state whether a company or a candidate proposes at a given step, nor which one does, as long as the given rules are observed.

the other members inside stableMatching.d.ts are:

interface Offer {
  from: number;
  to: number;
  fromCo: boolean; // If the offer is from a company
}

interface Run {
  trace: Offer[];
  out: Hire[];
}

type StableMatcherWithTrace = (companies: number[][], candidates: number[][]) => Run;

An Offer is an object with three fields that represents a proposal from one party member to a member of another party (company -> candidate or candidate -> company). A Run is an object that represents the series of steps an algorithm took (trace) to produce a solution (out). A StableMatcherWithTrace is just like a StableMatcher, but it returns a Run.

Implement stableMatchingRunOracle inside of oracles.ts.

export function stableMatchingRunOracle(f: (companies: number[][], candidates: number[][]) => Run): void {
  // TODO
}

This function should test the provided implementation of stable matching. It should check that:

The offer sequence in the trace is valid, made according to the given algorithm, starting with all parties unmatched
The trace need not be a complete algorithm run, it may stop at any point
The produced matching (out) is indeed the result of the offers in the trace

EXAMPLES:
Assume that we have candidates Alice, Bob, and Charles, and companies Amazon, Boeing, and Cisco. The candidate preference matrix could look like this:

       First Preference Second Preference   Third Preference

Alice (0) 0 (Amazon) 1 (Boeing) 2 (Cisco)
Bob (1) 0 (Amazon) 2 (Cisco) 1 (Boeing)
Charles (2) 2 (Cisco) 1 (Boeing) 0 (Amazon)
This means that Alice’s preferences are Amazon, Boeing, and Cisco, in that order. Bob’s preferences are Amazon, Cisco, and Boeing, in that order. Charles’ preferences are Cisco, Boeing, and Amazon, in that order. The corresponding number[][] would look like this:

[
  [0, 1, 2],
  [0, 2, 1],
  [2, 1, 0],
];

The company preference matrix could look like this:

       First Preference Second Preference   Third Preference

Amazon (0) 0 (Alice) 2 (Charles) 1 (Bob)
Boeing (1) 0 (Alice) 1 (Bob) 2 (Charles)
Cisco (2) 0 (Alice) 2 (Charles) 1 (Bob)
This means that Amazon’s preferences are Alice, Charles, and Bob, in that order. Boeing’s preferences are Alice Bob, and Charles, in that order. Cisco preferences are Alice, Charles, and Bob, in that order. The corresponding number[][] would look like this:

[
  [0, 2, 1],
  [0, 1, 2],
  [0, 2, 1],
];

A possible trace could look like this: [{from:1, to:1, fromCo:false}]. This means that Bob makes an offer to Boeing. This offer is invalid, since Bob’s top choice is Amazon, and Bob did not previously offer to Amazon in this run.

Another possible trace could be [{from:2, to:0, fromCo:true}]. This means that Cisco makes an offer to Alice. This is a valid offer, since Cisco’s top choice is Alice, and Cisco is unmatched. Alice’s top choice is Amazon, but being unmatched, they has to accept the offer. The result is that Alice and Cisco are now marked as matched. If later in the run Alice receives an offer from Amazon, Alice accepts and is matched to Amazon, and Cisco becomes unmatched.

Here is a longer trace:

[
  // Cisco -> Alice (accept - Alice is unmatched, both become matched)
  { from: 2, to: 0, fromCo: true },
  // Amazon -> Alice (accept - Alice prefers Amazon over their current match, both become matched, Cisco becomes unmatched)
  { from: 0, to: 0, fromCo: true },
  // Cisco -> Charles (accept - Charles is unmatched, both become matched)
  { from: 2, to: 2, fromCo: true },
];

This is a valid run. A valid resulting Hire array would be:

[
  { company: 0, candidate: 0 }, // Amazon and Alice
  { company: 2, candidate: 2 }, // Cisco and Charles
];

as those are the results of the trace

ACTUAL PROBLEM: I have written the following tests:

describe("Part B: stableMatchingRunOracle", () => {
  // Given an correct solution, no assertion should fail, and no errors should be thrown
  it("should accept STABLE_MATCHING_SOLUTION_1_TRACE", () => {
    expect(() => stableMatchingRunOracle(STABLE_MATCHING_SOLUTION_1_TRACE)).not.toThrow();
  });
  // Given an incorrect solution, some assertion should fail
  it("should reject FLAWED_STABLE_MATCHING_SOLUTION_1", () => {
    expect(() => stableMatchingRunOracle(FLAWED_STABLE_MATCHING_SOLUTION_1_TRACE)).toThrow(AssertionError);
  });
});

my code is passing the second one, but for the first one, theres an error in the trace function. specifically, its this error message:

 ● Part B: stableMatchingRunOracle › should accept STABLE_MATCHING_SOLUTION_1_TRACE

    expect(received).not.toThrow()

    Error name:    "AssertionError"
    Error message: "Final matching does not align with trace for company."`

I have gone over my code multiple times and I cant find what is wrong with the logic, and I dont have any Linter warnings also (im working on vscode). What is the problem here, and how can I solve it?

This is my code that I wrote:

import assert from "assert";

import type { Offer, StableMatcherWithTrace } from "../include/stableMatching.js";

export function generateInput(n: number): number[][] {
  // Helper function to shuffle an array
  function shuffle(array: number[]): void {
    for (let i = array.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [array[i], array[j]] = [array[j], array[i]]; // Swap elements
    }
  }

  // Generate a 2D array of preferences
  const preferences = [];
  for (let i = 0; i < n; i++) {
    const preference = Array.from({ length: n }, (_, index) => index);
    shuffle(preference);
    preferences.push(preference);
  }
  return preferences;
}

const NUM_TESTS = 100; // Change this to some reasonably large value
const N = 10; // Change this to some reasonable size

/**
 * Tests whether or not the supplied function is a solution to the stable matching problem.
 * @param makeStableMatching A possible solution to the stable matching problem
 * @throws An `AssertionError` if `makeStableMatching` in not a solution to the stable matching problem
 */
type Hire = { company: number; candidate: number };
type PreferenceList = number[][];
function existsBlockingPair(companies: PreferenceList, candidates: PreferenceList, hires: Hire[]): boolean {
  const companyToCandidate = new Map(hires.map(h => [h.company, h.candidate]));
  const candidateToCompany = new Map(hires.map(h => [h.candidate, h.company]));

  for (let company = 0; company < companies.length; company++) {
    const hiredCandidate = companyToCandidate.get(company);
    const companyPrefs = companies[company];

    for (const preferredCandidate of companyPrefs) {
      if (preferredCandidate === hiredCandidate) break; // No more preferred candidates
      const preferredCandidateCompany = candidateToCompany.get(preferredCandidate);

      // Check if preferredCandidateCompany is not undefined before proceeding
      if (preferredCandidateCompany !== undefined) {
        const preferredCandidatePrefs = candidates[preferredCandidate];

        if (preferredCandidatePrefs.indexOf(company) < preferredCandidatePrefs.indexOf(preferredCandidateCompany)) {
          // preferredCandidate prefers this company over their current one
          return true;
        }
      }
    }
  }

  return false;
}

type StableMatcher = (companies: number[][], candidates: number[][]) => Hire[];

export function stableMatchingOracle(makeStableMatching: StableMatcher) {
  for (let test = 0; test < NUM_TESTS; ++test) {
    const companies = generateInput(N);
    const candidates = generateInput(N);
    const hires = makeStableMatching(companies, candidates);

    assert.strictEqual(
      hires.length,
      N,
      "Each company must hire exactly one candidate, and each candidate must be hired by exactly one company."
    );

    const uniqueHires = new Set(hires.map(hire => `${hire.company}-${hire.candidate}`));
    assert.strictEqual(uniqueHires.size, hires.length, "There should be no duplicate hires.");

    const hasBlockingPair = existsBlockingPair(companies, candidates, hires);
    assert(!hasBlockingPair, "There should be no blocking pairs in the matching.");
  }
}

// Part B

/**
 * Tests whether or not the supplied function follows the supplied algorithm.
 * @param makeStableMatchingTrace A possible solution to the stable matching problem and its possible steps
 * @throws An `AssertionError` if `makeStableMatchingTrace` does not follow the specified algorithm, or its steps (trace)
 * do not match with the result (out).
 */
export function stableMatchingRunOracle(makeStableMatchingTrace: StableMatcherWithTrace): void {
  for (let i = 0; i < NUM_TESTS; ++i) {
    const companies = generateInput(N);
    const candidates = generateInput(N);
    const { trace, out } = makeStableMatchingTrace(companies, candidates);

    // Initialize tracking for matches and proposals made
    const companyMatches: (number | null)[] = new Array(N).fill(null) as (number | null)[];
    const candidateMatches: (number | null)[] = new Array(N).fill(null) as (number | null)[];
    const companyProposals: Set<string>[] = new Array(N).fill(null).map(() => new Set());
    const candidateProposals: Set<string>[] = new Array(N).fill(null).map(() => new Set());

    trace.forEach((offer: Offer) => {
      const { from, to, fromCo } = offer;
      const proposalSet = fromCo ? companyProposals[from] : candidateProposals[from];

      // Ensure the offer has not been made before and is in correct order
      assert(!proposalSet.has(to.toString()), "Duplicate or out-of-order offer detected.");
      proposalSet.add(to.toString());

      if (fromCo) {
        // Company to candidate offer
        const currentMatch = candidateMatches[to];
        if (currentMatch === null || companies[from].indexOf(to) < companies[currentMatch].indexOf(to)) {
          // Accept the offer
          if (currentMatch !== null) companyMatches[currentMatch] = null;
          companyMatches[from] = to;
          candidateMatches[to] = from;
        }
      } else {
        // Candidate to company offer
        const currentMatch = companyMatches[to];
        if (currentMatch === null || candidates[from].indexOf(to) < candidates[currentMatch].indexOf(to)) {
          // Accept the offer
          if (currentMatch !== null) candidateMatches[currentMatch] = null;
          companyMatches[to] = from;
          candidateMatches[from] = to;
        }
      }
    });

    // Validate the final matching
    out.forEach((hire: Hire) => {
      const { company, candidate } = hire;
      assert(companyMatches[company] === candidate, "Final matching does not align with trace for company.");
      assert(candidateMatches[candidate] === company, "Final matching does not align with trace for candidate.");
    });

    // Ensure every match in `out` was reached through the trace
    assert(out.every(hire => companyMatches[hire.company] === hire.candidate), "Mismatch in the number of hires and company matches.");
    assert(out.every(hire => candidateMatches[hire.candidate] === hire.company), "Mismatch in the number of hires and candidate matches.");
  }
}

i expected it to pass the tests described above. It keeps on failing despite multiple attempts to solve. I have gone over my code multiple times and I cant find what is wrong with the logic, and I dont have any Linter warnings also (im working on vscode). What is the problem here, and how can I solve it?

How to Read Object Array In Javascript

I have an object array in Javascript but it kept showing as undefined when I try to fetch a specific value.

May I know how can I read the values in the array?

Thank you.

enter image description here

function approveOrRejectTRF(primaryControl) {
    'use strict';
    if (!primaryControl) { return; }
    var formContext = primaryControl;
    var Id = formContext.data.entity.getId();

    var pageInput = {
        pageType: "webresource",
        webresourceName: "hsl_/html/TravelRequest/ApproveRejectButtonHtml.html",
        data: "&EntityId=" + Id
    };
    var navigationOptions = {
        target: 2,
        width: 800,
        height: 450,
        position: 1,
        title: "Approve/Reject"
    };
    Xrm.Navigation.navigateTo(pageInput, navigationOptions).then(
        function success(returnValue) {
            console.log(returnValue);
            console.log("Action : " + returnValue[0].actionVal);
            console.log("Comments : " + returnValue[0].commentsVal);
        },
        function error(e){
            // Handle errors
        }
    );
}

Edit: Debugger screenshot:
enter image description here

Waiting for a Pub/Sub Message from Google Cloud

So, I’ve been stuck on this for the past few days, and I’ve tried everything imaginable. For background, I’ll describe the web app, what’s supposed to happen, and where I’m stuck.

The web app I’ve made is a Next.js web app using google cloud resources to ingest a document, evaluate the document through document AI, and then the results of document AI are sent back to the user. I’ll list out the more granular steps below:

  1. User uploads document and submits it on the web app
  2. The document is stored on Cloud Storage
  3. There is an eventarc trigger attached to Cloud Storage that sends the newly uploaded document to a google workflow
  4. Within the google workflow, the document is sent to two Document AI processors: the normal OCR one, and the Summarizer one
  5. The responses are returned and sent to a cloud function
  6. Within the cloud function, the data is cleansed to be more digestible to the end user
  7. Within the cloud function, after the data is cleansed, it’s stored in firestore
  8. After it’s stored in firestore, it’s sent off to a Pub/Sub topic, with a push subscription attached to it. This subscription pushes to an API endpoint in the web app

This is the part that’s giving me trouble

  1. The API endpoint then receives the data and pushes it to the front end, where it is saved in the results state.

The issue I’m having is, how can I sit and wait inside the API route for the data from the Pub/Sub to arrive? Because if I immediately call the API endpoint that the data receives, it’s not going to be there. I have tried using websockets but with no luck. Would I use SSE, try websockets again, etc.? I would like to avoid using polling.

Below is the relevant client side code:
For further background, the submissionSuccess state is what shows a loading symbol while the data is processed on the server side. It’s a boolean value that is set to true if the document was successfully uploaded to Cloud Storage.

useEffect(() => {
    const getResults = async () => {
      try {
        const res = await fetch('/api/getFileData')
        const data = await res.json()

        if (!res.ok) {
          throw new Error(`${res.status} - ${res.statusText}`)
        }

        setResults(data)

      } catch (error) {
        console.error(`Error retrieving analysis results: ${error}`)
        openSnackbar({ message: 'There was an error retrieving your analysis results, please try again later', severity: 'error' })
      }
    }
  }, [submissionSuccess])

Relevant API route:

export default async function handler(req, res) {
  try {
    const payload = req.body.message.data
    const message = Buffer.from(payload, 'base64').toString('utf-8')
    let workflowResponse = JSON.parse(message)

    return res.status(200).json(workflowResponse)
  } catch (error) {
    console.error(`Error retrieving data from Pub/Sub subscription: ${error}`)
    return res.status(500).json({ error: 'Internal Server Error' })
  }
}

Why does the WebView in my Mac app behave differently from Safari?

I couldn’t find an answer on MDN Web Docs and Stack Overflow, Google Search so I’m posting a question.

The issue I’m experiencing is that…

Why does the ‘playbackRate Change’ button in the provided ‘controls’ of the HTML Audio attribute not work in my macOS project’s WebView?

I have a very simple HTML that plays audio.

<audio src="../Audio/013.mp3" controls="controls" style="width:370px;position: absolute;top:560px;left:200px;"></audio>

In Safari, the buttons supported in Controls work fine. However, in my Mac app, the playback speed change button doesn’t work.

Just like this

#Safari
enter image description here

# my Mac App
enter image description here

Deployment Target and Minimum Deployments macOS -> 12.0

Please note that it only supports macOS apps.

I have tried.

webView.allowsLinkPreview = false
webView.allowsBackForwardNavigationGestures = true 
webView.configuration.allowsAirPlayForMediaPlayback = true 
webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = true
webView.configuration.preferences.javaScriptEnabled = true
webView.configuration.defaultWebpagePreferences.allowsContentJavaScript = true
webView.configuration.mediaTypesRequiringUserActionForPlayback = .audio

App Sandbox -> outgoing Connections (Client) Check

Beginner question about accessing a DOM variable in a function globally

Can I add “let columns = document.getElementbyId(“column”)” globally to access my column class in my board function?



let black = document.querySelector("#black");
let color = document.querySelector("#color");
let numGrid = document.getElementById("gridValue");
let pad = document.getElementById("etch");
const GRID = document.querySelector("#gridInput");




numGrid.textContent = `${GRID.value} x ${GRID.value}`;
GRID.addEventListener("input", (event) => {
  numGrid.textContent = `${event.target.value} x ${event.target.value}`;
  clearPad();
  board(event.target.value);
});



function board (num) {
    for(let i = 0; i < num; i++) {
        let row = document.createElement("div");
        row.classList.add("row");
        pad.appendChild(row);

    for(let j = 0; j < num; j++) {
        let column = document.createElement("div");
        column.classList.add("column");
        row.appendChild(column);
      }

    }
 }

 function clearPad() {
  pad.textContent = '';
}


board(GRID.value);



I plan on adding a mouseover color option to the column class.

(JavaScript)sometimes returns as undefined. Why?

function getComputerChoice(randomLetterGen){

function randomLetterGen(){

    function randomNumGen(){
        return Math.floor(Math.random()*3);
    }

    let word = "rps";
    return word.charAt(randomNumGen());
}

let cpuInput;

if (randomLetterGen() == "r"){
    cpuInput = "rock";
} else if (randomLetterGen() == "p"){
    cpuInput = "paper";
} else if (randomLetterGen() == "s") {
    cpuInput = "scissors";
}
return cpuInput;

}

console.log(getComputerChoice());

I think there is an undefined option because of the ‘let cpuInput;’ but I dont understand why. I thought the if statement redefined the variable. Also, the undefined option only logs when ‘Math.random()*3’ is 2 or above. It doesnt appear otherwise. Why?

Cannot unzip zip file with window 10/11

I encountered a problem cannot unzip certain zip files with Window10/11.

I made a program which one downloads excel files as a zip file by using minizip-asm.min.js library.

Everytime try to unzip this zip file with window10/11, 0x80004005 : Unspecified error.

It can be unzipped by 7zip or such kind of programs, but it is impossible only Windows built-in programs.

How can I fix or handle it?

hers’s my js code

function gfn_exportExcel(dataJson, fn, pw) {

    var data = dataJson.data;
    var wch = dataJson.wch;

    // step 1.making workbook 
    var wb = XLSX.utils.book_new();

    // step 2. making excel sheet
    var newWorksheet = XLSX.utils.aoa_to_sheet(data);

    // step 2-2. setting columns
    newWorksheet["!cols"] = gfn_fitToColumnExcel(data, wch);

    // step 3. naming workbook
    XLSX.utils.book_append_sheet(wb, newWorksheet, "data");

    // step 4. making excel file
    var wbout = XLSX.write(wb, {bookType:'xlsx',  type: 'binary'});

    // step 5. export excelfile or export files as zip file
    if( pw ){
        var mz = new Minizip();
        mz.append('data.xlsx', gfn_s2ab(wbout), {password : pw});
        saveAs(new Blob([mz.zip()],{type:"application/octet-stream"}), fn + ".zip");
    } else {
        saveAs(new Blob([gfn_s2ab(wbout)],{type:"application/octet-stream"}), fn + ".xlsx");
    }
}

Perfectly align textarea and canvas

A feature like text box is common in whiteboard applications. When I tried to implement this feature, I found it’s hard to align the text area and the canvas. Usually the text on canvas fades and the text area over it shows for editing the content when a user clicks on the text box.

In the following example, I purposely make them overlap to demonstrate the offset they have in y axis.

enter image description here

import { useEffect, useRef } from 'react';
import './App.css';

const WIDTH = 300;
const HEIGHT = 300;
const FONT_SIZE = 80;

function App() {
  const canvasRef = useRef()

  useEffect(() => {
    const canvas = canvasRef.current
    canvas.width = WIDTH * devicePixelRatio
    canvas.height = HEIGHT * devicePixelRatio
    canvas.style.width = `${WIDTH}px`
    canvas.style.height = `${HEIGHT}px`
    const context = canvas.getContext('2d')
    context.fillStyle = 'red'
    context.font = `${FONT_SIZE * devicePixelRatio}px sans-serif`
    const metrics = context.measureText('M')
    context.clearRect(0, 0, WIDTH * devicePixelRatio, HEIGHT * devicePixelRatio)
    context.fillText('Hello', 0, metrics.fontBoundingBoxAscent)
    context.fillText('World', 0, metrics.fontBoundingBoxAscent + FONT_SIZE * devicePixelRatio)
  }, [])


  return (
    <div className="App">
      <div className="container">
        <canvas ref={canvasRef} />
        <textarea value="Hello World" style={{ width: `${WIDTH}px`, height: `${HEIGHT}px` }}/>
      </div>
    </div>
  );
}

export default App;
.App {
  text-align: center;
}

.container {
  width: 300px;
  height: 300px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;

  textarea {
    position: absolute;
    inset: 0;
    outline: none;
    border: none;
    resize: none;
    padding: 0;
    line-height: 1;
    width: 300px;
    height: 300px;
    font-size: 80px;
    background-color: transparent;
    font-family: sans-serif;
  }
}

codesandbox

Does anyone know what makes the difference between the text positioning?

Downloading Javascript object as a .json file, but JSON is not formatted

I have a function that is taking a javascript object and attempting to download it into a .json file, but it’s being printed as flat text. Is there any way I can get this to be .json formatted in the file? Also would prefer not to have to install any third-party libraries if possible.

downloadJSON(jsonFile: any, fileName: string){
        let sJson = JSON.stringify(jsonFile);
        let file = new Blob([sJson], {type: 'application/json'})
        let element = document.createElement('a');
        let url = URL.createObjectURL(file);
        element.setAttribute('href', url);
        element.setAttribute('download', fileName);
        element.style.display = 'none';
        document.body.appendChild(element);
        element.click(); // simulate click
        document.body.removeChild(element);
    }