UpdateViaCache doesn’t work with Safari [Service Worker]

I’d like my application to make as few requests to the server as possible. In this context, I use updateViaCache : “all” when registering my worker. On Android devices, I don’t get any requests at all. On iOS, the application makes a request for the Worker each time a new page is loaded. The problem seems to come from the browser, Safari in this case.
I read this thread from 2018:
https://bugs.webkit.org/show_bug.cgi?id=187435
It concludes as follows:

In any case, the patch that is about to land should align our behavior with Chrome and you should still only one serviceworker.js load per page load.

As I mentioned earlier, you can opt into using the disk cache so that your server will be hit only when the serviceworker.js script in the HTTP cache has expired. To do so:

navigator.serviceWorker.register(serviceWorkerUrl, { updateViaCache: “all” });

This is on registration, unlike what you stated earlier.

Which suggests that it should work, but it doesn’t seem to.

Here’s how I register my Service Worker:

async function registerServiceWorker() {
    try {
        const registration = await navigator.serviceWorker.register(
            `/service-worker.js?v=${SW_VERSION}`,
            { updateViaCache: 'all' }
        );
        if (LOG) console.log("Service Worker enregistré avec le scope :", registration.scope);
    } catch (error) {
        console.error("Erreur lors de l'enregistrement du Service Worker :", error);
    }
}

PS : SW_VERSION is used to force the worker service to be updated via the server when it is updated.

How to getting a job after gap [closed]

I worked as a Junior Software Engineer (Angular Developer) in a product-based company (WFH) but had to leave due to health issues, leaving me with a one-year gap. I’m now upskilling with a Full-Stack Development course and learning backend development.

However, I’m facing interview issues—HR is not accepting my gap, and my previous salary is considered high for my experience. How can I justify my gap and handle salary expectations to get a job? Should I accept a lower salary or manage some mock experience?

my skills set is JAVASCRIPT, React js , node js , Mern

Using Javascript, how to get html page from a url?

I’m trying to get an html page from a url using Javascript, I have the following html file with javascript :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Fetch HTML Example</title>
</head>
<body>
    <div id="content"></div>

    <script>
        const url = 'https://nmjava.com';

        async function fetchHTML() {
            try {
                const response = await fetch(url);
                if (!response.ok) {
                    throw new Error('Network response was not ok ' + response.statusText);
                }
                const html = await response.text();
                document.getElementById('content').innerHTML = html;
            } catch (error) {
                alert('There has been a problem with your fetch operation : ' + error);
            }
        }

        fetchHTML();
    </script>
</body>
</html>

This is the error I got after loading the page: “There has been a problem with your fetch operation : TypeError: Failed to fetch”

How to get the text from that page ?

How to fix error initializing offset in vue quill

I have problem initializing vue quill to apply in a Vue3 project about a note taking function, i can make note easily but when modifying it, it return offset error everytime i click or type on the quill editor. Here is my error

quill.js?v=870ff25b:12570 Uncaught TypeError: Cannot read properties of null (reading 'offset')
    at quill.js?v=870ff25b:12570:26
    at Array.map (<anonymous>)
    at Selection.normalizedToRange (quill.js?v=870ff25b:12567:31)
    at Selection.getRange (quill.js?v=870ff25b:12556:25)
    at Selection.update (quill.js?v=870ff25b:12691:43)
    at quill.js?v=870ff25b:12452:12
    at quill.js?v=870ff25b:12338:9
    at Array.forEach (<anonymous>)
    at Emitter.handleDOM (quill.js?v=870ff25b:12332:43)
    at quill.js?v=870ff25b:12310:23

And here is my code:

<template>
  <section id="view-note-page" class="container mt-4">
    <div class="note-header-container mb-3 d-flex justify-content-between align-items-center">
      <div class="note-title-container">
        <label for="note-title" class="note-title-label">Title:</label>
        <input
            id="note-title"
            type="text"
            v-model="noteData.title"
            class="note-title-input"
            placeholder="Enter note title"
        />
      </div>
      <button class="btn btn-primary btn-save-changes" @click="saveNote">Save Changes</button>
    </div>

    <div id="post-editor" class="mb-3 flex-grow-1">
      <div id="quill-editor"></div>
    </div>
  </section>
</template>

<script>
import { nextTick } from "vue";
import Quill from "quill";
import "quill/dist/quill.snow.css";
import { toast } from "vue3-toastify";
import "vue3-toastify/dist/index.css";
import { noteService } from "@/services/note.service";

export default {
  name: "ViewNotePage",
  props: {
    noteId: {
      type: [String, Number],
      required: true,
    },
  },
  data() {
    return {
      noteData: {
        title: "",
        content: "",
      },
      quillEditor: null,
    };
  },
  methods: {
    async fetchNote() {
      try {
        const note = await noteService.fetchNoteFromId(this.noteId);
        this.noteData = note;
        await this.updateQuillContent(note.content);
      } catch (error) {
        console.error("Failed to fetch the note:", error);
        toast.error("Failed to fetch the note.", { autoClose: 2000 });
      }
    },
    async initializeQuill() {
      try {
        await nextTick();
        const editorElement = document.getElementById("quill-editor");

        if (editorElement) {
          this.quillEditor = new Quill(editorElement, {
            theme: "snow",
            modules: {
              toolbar: [
                ["bold", "italic", "underline"],
                [{list: "ordered"}, {list: "bullet"}],
                [{header: [1, 2, 3, false]}],
                ["link"],
                ["clean"],
              ],
            },
          });

          this.quillEditor.on("text-change", () => {
            this.noteData.content = JSON.stringify(this.quillEditor.getContents());
          });
        }
      } catch (error) {
        console.error("Failed to initialize Quill editor:", error);
      }
    },
    async updateQuillContent(content) {
      try {
        if (this.quillEditor) {
          const delta = content ? JSON.parse(content) : {ops: []};
          this.quillEditor.setContents(delta);
        }
      } catch (error) {
        console.error("Failed to update Quill content:", error);
      }
    },
    async saveNote() {
      try {
        if (!this.noteData.title || !this.noteData.content) {
          toast.error("Please provide a title and content for the note.", {autoClose: 2000});
          return;
        }

        await noteService.updateNote(this.noteId, this.noteData);
        toast.success("Note updated successfully!", {autoClose: 2000});
        this.$emit("update", this.noteData);
      } catch (error) {
        console.error("Failed to save the note:", error);
        toast.error("Failed to update the note.", {autoClose: 2000});
      }
    },
  },
  async mounted() {
    try {
      await this.initializeQuill();
      await this.fetchNote();
    } catch (error) {
      console.error("Error during component setup:", error);
    }
  },
  watch: {
    noteId: {
      immediate: true,
      handler(newNoteId) {
        this.fetchNote();
      },
    },
  },
};
</script>

I tried to use something similar to this I found on github but it doesnot work

// ✅  works with quill2
let quill: Quill | null = null

onMounted(() => {
   quill = new Quill(...)
})

How to get html page from a url with Javascript? [closed]

I’m trying to get an html page from a url using Javascript, I have the following html file with javascript, but it’s not working, how to make it work ?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Fetch HTML Example</title>
</head>
<body>
    <div id="content"></div>

    <script>
        // URL of the HTML page you want to fetch
        const url = 'https://nmjava.com';

        // Function to fetch and display the HTML content
        async function fetchHTML() {
            try {
                const response = await fetch(url);
                if (!response.ok) {
                    throw new Error('Network response was not ok ' + response.statusText);
                }
                const html = await response.text();
                document.getElementById('content').innerHTML = html;
            } catch (error) {
                alert('There has been a problem with your fetch operation : ' + error);
            }
        }

        // Call the function to fetch and display the HTML content
        fetchHTML();
    </script>
</body>
</html>

In this example:

The fetch function is used to make a GET request to the specified URL.
The response is checked to ensure it was successful.
The HTML content is extracted from the response using the text method.
The fetched HTML content is then inserted into a div with the ID content.

Cannot place a transcaction on a smart contract through the front end

Im trying to use a bet function i have build on a smart contract but keep getting this error here:

page.js:92 Error placing bet: Error: transaction execution reverted (action="sendTransaction", data=null, reason=null, invocation=null, revert=null, transaction={ "data": ""

I can place bets using via my script on solidity by command :

`address PredictionMarketAddress =
0x700b6A60ce7EaaEA56F065753d8dcB9653dbAD35; // Deployed contract address
PredictionMarket public market = PredictionMarket(PredictionMarketAddress);

uint gambler1 =
    0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d;

function setUp() public {}

function run() public {
    // Start broadcasting as gambler1
    vm.startBroadcast(gambler1);

    // Place a bet on Kamala with 10 ether
    market.bet{value: 8 ether}(PredictionMarket.Side.Trump);

    // Stop broadcasting
    vm.stopBroadcast();
}`

What i have checked: The ABI, contract address and signer are working fine. What is also weird is that from the same wallet i use by command i can bet but when using metamask im getting this gas error thing but even when inputing gas limits i still get the same error.

Here is the page front end not including Index.js which is fine :

const SIDE = {
  KAMALA:0,
  TRUMP:1
}


export default function Home() {
  const [signer, setSigner] = useState(undefined);
  const [predictionMarket, setPredictionMarket] = useState(undefined);
  const [betPredictions, setBetPredictions] = useState(undefined);
  const [myBets, setMyBets] = useState(undefined)

  // Wait for the prediction market to be ready AND then = we calculate the market and show the chart
  useEffect(() => {
    const init = async () => {
      // This gets the PredictionMarket contract instance
      const bets = await Promise.all([
        predictionMarket.betsPerCandidate(SIDE.KAMALA),
        predictionMarket.betsPerCandidate(SIDE.TRUMP)
      ]);
      console.log(bets)

      // Here, you're setting the `betPredictions` data for the chart
      const betPredictions = {
        labels: ["Trump", "Kamala"],
        datasets: [{
          data: [bets[1].toString(), bets[0].toString()],
          backgroundColor: [
            '#FF6384',
            '#36A2EB'
          ],
          hoverBackgroundColor: [
            '#FF6384',
            '#36A2EB'
          ]
        }]
      };
        // Set the user's bets
        const signerAddress = await signer.getAddress();
        const myBets = await Promise.all([
        predictionMarket.betsPerGambler(signerAddress, SIDE.TRUMP),
        predictionMarket.betsPerGambler(signerAddress, SIDE.KAMALA),
      ])
      // Set state for bets and prediction data
      setMyBets(myBets)
      setBetPredictions(betPredictions)
      
    };
    console.log("PredictionMarket Contract:", predictionMarket);

    // Only run if both `predictionMarket` and `signer` are defined
    if (predictionMarket && signer) init();
  }, [predictionMarket])
  

  const placeBet = async (side, e) => {
    e.preventDefault();
    
    const betAmount = e.target.elements[0].value.trim();
  
    // Validate bet amount
    if (!betAmount || isNaN(betAmount) || Number(betAmount) <= 0) {
      console.error("Invalid bet amount.");
      return;
    }
  
    try {
      // Send the bet transaction to the PredictionMarket smart contract
      const txResponse = await predictionMarket.bet(
        side.toString(),
        { value: ethers.parseEther(betAmount), gasLimit: 1000000 }
      );
      
      
      
  
      const txReceipt = await txResponse.wait();
      console.log(txReceipt);
    } catch (error) {
      console.error("Error placing bet:", error);
  
      // Log the transaction data for debugging
      console.log("Transaction data:", {
        action: "placeBet",
        betAmount,
        side,
      });
  
      // Try more specific error handling
      if (error.data) {
        console.error("Error Data:", error.data);
      }
      if (error.reason) {
        console.error("Error Reason:", error.reason);
      }
      if (error.error) {
        console.error("Nested Error:", error.error);
      }
      if (error.info) {
        console.error("Error Info:", error.info);
      }
      if (error.data) {
        console.error("Error Data:", error.data);
      }
    }
  }
  
  


  const withdrawGain = async () => {
    try {
      const txResponse = await predictionMarket.withdraw();
      const txReceipt =  await txResponse.wait();
      console.log(txReceipt)
    } catch(e){
      console.log(e)
    }
  }

Edit: Also here is the smart contract bet function

function bet(Side _side) external payable {
        require(electionFinished == false, "election is finished"); // Ensure election is still ongoing
        require(msg.value > 0, "Bet amount must be greater than 0"); // Ensure that the bet amount is greater than 0

        // Update bets
        betsPerCandidate[_side] += msg.value;
        betsPerGambler[msg.sender][_side] += msg.value;

        emit BetPlaced(msg.sender, _side, msg.value); // Log the bet placement

enter code here

Thanks!

Visible grey edges inside Html-canvas

Hello i am trying to export a uvmap for a model and i am filling triangles(meshes) with color, it works but i always see grey mesh lines. i tried to draw lines if i draw the lines with different color i can see lines but if i chose same color its always grey
Any idea how to accomplish that thanks

    const { Scene } = tshirtNodes; // Access Three.js state
    const geometry = Scene.children[0].geometry; // Access geometry of the 3D model
    const uvAttribute = geometry.attributes.uv; // UV data
    const indexAttribute = geometry.index; // Triangle indices
    const canvasSize = 10000; // Canvas size
    const uvArray = uvAttribute.array; // UV coordinates
    const indexArray = indexAttribute.array; // Triangle indices
    const renderUVMap = () => {
              console.log("render uvmap");
              for (let i = 0; i < indexArray.length; i += 3) {
                const i1 = indexArray[i] * 2;
                const i2 = indexArray[i + 1] * 2;
                const i3 = indexArray[i + 2] * 2;
        
                const uv1 = { x: uvArray[i1], y: uvArray[i1 + 1] };
                const uv2 = { x: uvArray[i2], y: uvArray[i2 + 1] };
                const uv3 = { x: uvArray[i3], y: uvArray[i3 + 1] };
        
                let part = null;
                for (const [key, condition] of Object.entries(uvConditions)) {
                  if (
                    isWithinCondition(uv1, condition) ||
                    isWithinCondition(uv2, condition) ||
                    isWithinCondition(uv3, condition)
                  ) {
                    part = key;
                    break; // Stop once the part is determined
                  }
                }
        
                if (!part) continue; 
                if (partColorType[part] === "single") {
                  const color = colorsForparts[part];
                  if (!color) continue;
        
                  const [r, g, b] = color.map((c) => Math.floor(c * 255));
                  ctx.fillStyle = `rgb(${r}, ${g}, ${b})`;
        
                  ctx.beginPath();
        
                  ctx.moveTo(uv1.x * canvasSize, uv1.y * canvasSize);
                  ctx.lineTo(uv2.x * canvasSize, uv2.y * canvasSize);
                  ctx.lineTo(uv3.x * canvasSize, uv3.y * canvasSize);
                  ctx.closePath();
                  ctx.fill();
        
                  // ctx.strokeStyle = `rgb(${r}, ${g}, ${b})`;
                  // ctx.beginPath();
                  // ctx.moveTo(uv1.x * canvasSize, uv1.y * canvasSize);
                  // ctx.lineTo(uv2.x * canvasSize, uv2.y * canvasSize);
                  // ctx.lineTo(uv3.x * canvasSize, uv3.y * canvasSize);
                  // ctx.lineWidth = 0.05; 
                  // ctx.stroke();
                } 
              }
            };

an example image

At the left side you can see meshes as grey and right side green when i chose different color than the triangles

Sort an array of object by the value of a child object

I’m getting some json in the following structure:

[
    {
        "name": "First object", 
        "info": [
            "2 people",
            "this is a description"
        ]
    },
    {
        "name": "Second object", 
        "info": [
            "this is a description",
            "1 furniture"
        ]
    },
    {
        "name": "Third object", 
        "info": [
            "3 animals",
            "this is a description"
        ]
    },
]

I know how to sort arrays by values (like if I was supposed to sort only by name), but how can I sort it based on the number in the array? They will not always be at the same index, so I guess I will need a sorting routine to put them in the right place or something. The array value with a number will be the only value containing a digit. And that will be used for sorting. So the output should be:

1 furniture - Second object
2 people - First object
3 animals - Third object

Will I have to traverse the whole array, or is there a simpler way to do it? Any help would be appreciated so I’m able to wrap my head around it.

js try catch then log error with the stack trace

// I have many fns defined by other people. Those fns may throw error.
var fns = [
  () => 1,
  () => 2,
  () => {
    throw new Error('3');
  },
  () => 3,
  () => {
    throw 5
  }, // I can not imagine fn must throw Error instance.
];
// I need to call these fns one by one and catch their errors.
fns.forEach(fn => {
  try {
    fn();
  } catch (error) {
    console.error(error);
  }
});

At here, I click on VMxxx:xx, but cannot locate to where the throw really happened.

VM531:14  Error: 3
    at fns (<anonymous>:5:17)
    at <anonymous>:12:5
    at Array.forEach (<anonymous>)
    at <anonymous>:10:5
(anonymous) @ VM531:14
(anonymous) @ VM531:10
VM531:14  5
(anonymous) @ VM531:14
(anonymous) @ VM531:10
undefined


fns[2]()
// But here VMxxx:xx can locate to code throw really happened.
VM531:5 Uncaught Error: 3
    at Array.fns (<anonymous>:5:17)
    at <anonymous>:1:7

How can I call functions which may throw error, then log the error and stack trace?

I tried replace console.error with console.trace, but it doesn’t help.

Office Js Addin for Word translation

I want to have a addin that loops through the paragraphs in a document, does an api call to a translation service, returns a new paragraph, and inserts this into word again.

I have gotten it to do this, however i cant make it preserve the original formatting and it seems to remove images when using paragraph.insertText function. I have tried using InsertHtml aswell but i cant seem to get it to work properly. Does anyone know of a good way to do this?

I want to only change text in the document and need everything else to stay the same.

This is the code i have so far:

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import './index.css';


const customDictionaryEnToNb = [
];

const customDictionaryNbToEn = customDictionaryEnToNb.map(({ from, to }) => ({
  from: to,
  to: from,
}));


function preserveCase(source, target) {
  if (source === source.toUpperCase()) return target.toUpperCase();
  const isTitleCase = source[0] === source[0].toUpperCase() && source.slice(1) === source.slice(1).toLowerCase();
  if (isTitleCase) return target.charAt(0).toUpperCase() + target.slice(1).toLowerCase();
  return target.toLowerCase();
}


function applyCustomDictionary(text, direction) {
  const dict = direction === 'enToNb' ? customDictionaryEnToNb : customDictionaryNbToEn;
  dict.sort((a, b) => b.from.length - a.from.length);
  let result = text;
  dict.forEach(({ from, to }) => {
    const regex = new RegExp(from, 'gi');
    result = result.replace(regex, (match) => preserveCase(match, to));
  });
  return result;
}


async function callAzureTranslator(text, direction) {
  const key = process.env.REACT_APP_AZURE_TRANSLATOR_KEY;
  const region = process.env.REACT_APP_AZURE_TRANSLATOR_REGION;
  if (!key || !region) throw new Error('Azure Translator key/region is missing.');
  const fromLang = direction === 'enToNb' ? 'en' : 'nb';
  const toLang = direction === 'enToNb' ? 'nb' : 'en';
  const endpoint = `https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&from=${fromLang}&to=${toLang}`;
  const response = await axios.post(endpoint, [{ Text: text }], {
    headers: {
      'Ocp-Apim-Subscription-Key': key,
      'Ocp-Apim-Subscription-Region': region,
      'Content-Type': 'application/json',
    },
  });
  const translated = response.data[0]?.translations[0]?.text;
  if (!translated) throw new Error('Translation response not in expected format.');
  return translated;
}


async function translateDocument(direction) {
  return Word.run(async (context) => {
    try {
      const paragraphs = context.document.body.paragraphs;
      console.log('Loading paragraph items...');
      paragraphs.load('items');
      await context.sync();

      const total = paragraphs.items.length;
      console.log(`Starting translation of ${total} paragraphs.`);

      let processed = 0;
      for (let i = 0; i < total; i++) {
        try {
          const paragraph = paragraphs.items[i];
          paragraph.load('text, font, inlinePictures');
          await context.sync();

          const paraText = paragraph.text;
          const hasImages = paragraph.inlinePictures.items.length > 0;
          console.log(`Paragraph ${i}:`, {
            text: paraText,
            hasText: !!paraText,
            hasImages,
          });

          if (!paraText) {
            console.log(`Paragraph ${i}: Skipping empty paragraph.`);
            processed++;
            continue;
          }

          const fontProps = {
            bold: paragraph.font.bold,
            italic: paragraph.font.italic,
            underline: paragraph.font.underline,
          };

          const overriddenText = applyCustomDictionary(paraText, direction);
          const translatedText = await callAzureTranslator(overriddenText, direction);

         
          paragraph.insertText(translatedText, 'Replace');
          paragraph.font.bold = fontProps.bold;
          paragraph.font.italic = fontProps.italic;
          paragraph.font.underline = fontProps.underline;

          await context.sync();
          console.log(`Paragraph ${i}: Translated with formatting and pictures preserved.`);
          processed++;

          window.dispatchEvent(
            new CustomEvent('updateProgress', { detail: { processed, total } })
          );
          await new Promise(resolve => setTimeout(resolve, 50));
        } catch (err) {
          if (err.message.includes('ItemNotFound')) {
            console.warn(`Paragraph ${i}: ItemNotFound, skipping.`);
            processed++;
          } else {
            console.error(`Paragraph ${i}: Error processing:`, err);
          }
        }
      }

      console.log('Translation completed.');
    } catch (err) {
      console.error('Error in translateDocument:', err);
      throw err;
    }
  }).catch(err => {
    console.error('Word.run failed:', err);
  });
}


function App() {
  const [message, setMessage] = useState('');
  const [progress, setProgress] = useState(0);
  const [currentParagraph, setCurrentParagraph] = useState(0);
  const [totalParagraphs, setTotalParagraphs] = useState(0);

  useEffect(() => {
    const progressListener = (e) => {
      const { processed, total } = e.detail;
      setCurrentParagraph(processed);
      setTotalParagraphs(total);
      setProgress(Math.round((processed / total) * 100));
    };
    window.addEventListener('updateProgress', progressListener);
    return () => window.removeEventListener('updateProgress', progressListener);
  }, []);

  async function handleTranslate(direction) {
    setMessage(`Translating paragraphs -> ${direction} ...`);
    setProgress(0);
    setCurrentParagraph(0);
    setTotalParagraphs(0);
    try {
      await Office.onReady();
      console.log("Office is ready.");
      const total = await Word.run(async (context) => {
        console.log('Word Version:', await context.application.version);
        const paragraphs = context.document.body.paragraphs;
        paragraphs.load('items');
        await context.sync();
        console.log('Paragraph count retrieved:', paragraphs.items.length);
        return paragraphs.items.length;
      });
      setTotalParagraphs(total);
      if (total === 0) {
        setMessage("No paragraphs found to translate.");
        return;
      }
      await translateDocument(direction);
      setMessage('Translation complete!');
    } catch (err) {
      console.error('Translation error:', err);
      setMessage(`Error: ${err.message}. Check console for details.`);
    }
  }

  return (
    <div className="App">
      <h1>Word Translator</h1>

      <div style={{ textAlign: 'center', marginTop: '1rem' }}>
        <button onClick={() => handleTranslate('enToNb')}>Translate to Norwegian</button>
        <button onClick={() => handleTranslate('nbToEn')}>Translate to English</button>
      </div>
      {message && <p style={{ marginTop: '1rem', fontWeight: 'bold' }}>{message}</p>}
      {totalParagraphs > 0 && (
        <div className="progress-container">
          <div className="progress-label">
            Paragraph {currentParagraph} of {totalParagraphs} ({progress}%)
          </div>
          <br />
          <progress value={progress} max="100" />
        </div>
      )}
    </div>
  );
}

export default App;

Need to Make My Multiplayer Quiz Game Real-Time with REST API [closed]

I’m working on a real-time multiplayer quiz game where two users should join the same game session before it starts. The problem I’m facing is making sure two users are matched properly using a REST API instead of WebSockets (my team leader insists on REST).

So far I have

  1. The Game Flow:

    • A user enters the game and sends a request to the API to join.
    • Every 10 seconds, the system checks if another user has also joined.
    • Once two users are in the same session, the game should start.
  2. The API Endpoint I’m Using:

    The API to register a user for a game session:

    POST /api/RequestQuestionAnswers/Add
    

    Request Body:

    {
      "userId": 4,
      "isOnline": 1,
      "date": "string"
    }
    

    Response:

    {
      "isSuccess": true,
      "message": "Added RequestQuestionAnswer",
      "data": {
        "status": "",
        "userIdOne": 0,
        "userIdTwo": 0,
        "requestQuestionAnswerId": 211
      }
    }
    

    At this point, no opponent has joined yet.

  3. How Matching Works:

    • If another user sends a request (e.g., userId: 5), the response changes:
    {
      "isSuccess": true,
      "message": "Added RequestQuestionAnswer",
      "data": {
        "status": "Now You can Play",
        "userIdOne": 5,
        "userIdTwo": 4,
        "requestQuestionAnswerId": 212
      }
    }
    

    Now, user 4 and user 5 are matched, and they can start the game.

Current Issues and What I Need Help With:

  1. Making Sure Two Users Are Matched Properly

    • Right now, every 10 seconds, I send another request, but I’m not sure if this is the best way to check if an opponent has joined.
    • Should I use a different API request for checking the status instead of creating new entries?
  2. Managing Users in Two Tabs for Testing

    • I want to test this in two different tabs in Chrome. What’s the best way to define and differentiate users in separate tabs?
    • Should I store user IDs in localStorage or session cookies to simulate two different users?

What I Plan to Do Next:

  • Once two users are confirmed to be in the game, start the quiz.
  • Sync the questions so that both users answer at the same time.

promoteId in Mapbox Studio

I use a geojson file such as the following to upload data as a Mapbox tileset to Mapbox Studio. The tileset is then used for a Mapbox style created with Studio. Within my file, I assign both a top-level ID as well as property IDs for each feature within the feature collection:

{
  "type":"FeatureCollection",
  "features": [
    { "type": "Feature",
      "id": 1
      "geometry": { ... },
      "properties": { "id": 1, ...}
    },
    { "type": "Feature",
      "id": 2
      "geometry": { ... },
      "properties": { "id": 2, ...}
    }
  ]
}

Now, my expectation was for mapbox to use the top-level feature IDs as the corresponding IDs when querying for features like so:

map.on('mouseenter', 'my-layer', (e) => {
  if (e.features.length > 0) {
    console.log(e.features);
  }
});

As you can see here, however, IDs are not equal:

divering IDs

I am aware of promoteId, however, since I am not adding a source dynamically, I am at a loss at how to apply the same logic. Is there a way to “enable” promoteId within Mapbox Studio?

What is an alternative to passing a value from a child component to a parent component in ReactJs?

I am essentially trying to make a popup that is triggered by clicking on a child component. The only problem is that I cannot surround the child component with a div that has the onClick trigger because then there is space outside of the child that triggers the pop-up upon clicking. I would like to put the onClick in the child code, however I am not sure how the trigger would be recognized if the useState is initialized in the child component. What can I do from this point?

Parent Component:

export default function ParentComponent() {
  const[isPopped, setIsPopped] = useState(false);
  
  return (
    <div>
      <div>
        <div className="row">
          <div>
            <ChildComponent />
          </div>
          <div>
            <ChildComponent time={20} unit={min} />
          </div>
        </div>
        <div className="row">
          <div>
            <ChildComponent time={1} unit={hr} />
          </div>
          <div>
            <ChildComponent time={2} unit={hr} />
          </div>
        </div>
      </div>
      <ConfirmChoice trigger={isPopped} setTrigger={setIsPopped} />
    </div>
  );
}

Child Component:

export default function ChildComponent({
  time = 15,
  unit = "min"
}) {
  return (
    <div onClick={() => setIsPopped(true)>
      <div>{time}{unit}</div>
      <p>image</p>
    </div>
  );
}

Redirect after register React + Redux Toolkit + async thunk

I am writing a small application with registration and authorization logic. I managed to register. If successful, I fill in all the states as it should be, and if something goes wrong, I get the isError = true status and the error text itself.

The problem is that I want to redirect the user to another page ONLY IF the registration is successful.

I use:
React + TS + Redux-toolkit with createAsyncThunc + react-router-dom

react-hook-form + Zod

My register component

import clsx from 'clsx'
import { FC } from 'react'

import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { useNavigate } from 'react-router-dom'

import { useAppDispatch, useAppSelector } from '../../store/hooks'
import { registerUser } from '../../store/slices/userSlice'

import { FormInput } from '../../components/FormInput/FormInput'
import { Button } from '@gravity-ui/uikit'

import { registerSchema, TRegisterSchema } from '../../models/AuthSchema'

import styles from './RegisterForm.module.sass'

interface AuthFormProps {
    className?: string
}

export const RegisterForm: FC<AuthFormProps> = ({ className }) => {
    const dispatch = useAppDispatch()
    const { errorText } = useAppSelector((state) => state.userSlice)
    const navigate = useNavigate()

    const {
        register,
        handleSubmit,
        formState: { errors },
        reset,
    } = useForm<TRegisterSchema>({
        resolver: zodResolver(registerSchema),
    })

    const onSubmit = async (data: TRegisterSchema) => {
        dispatch(registerUser(data))
        reset()
    }

    return (
        <div className={clsx(className, styles.wrapper)}>
            <form className={styles.form} onSubmit={handleSubmit(onSubmit)}>
                <FormInput
                    title='Email'
                    register={register}
                    registerName='email'
                    errorText={errors.email?.message}
                    isErorr={!!errors.email}
                />
                <FormInput
                    title='Name'
                    register={register}
                    registerName='name'
                    errorText={errors.name?.message}
                    isErorr={!!errors.name}
                />
                <FormInput
                    title='Password'
                    register={register}
                    registerName='password'
                    errorText={errors.password?.message}
                    isErorr={!!errors.password}
                />
                <Button type='submit' className={styles.button} size='xl'>
                    Register
                </Button>
            </form>
        </div>
    )
}

My slice with async thunk

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
import UserService from '../../api/Services/UserService'
import { AxiosError } from 'axios'

interface IInitialState {
    user: {
        accessToken: string
        email: string
        name: string
    }
    isError: boolean
    errorText: string
    isLoading: boolean
}

interface IAuthInfo {
    name: string
    email: string
    password: string
}

export const registerUser = createAsyncThunk(
    'user/register',
    async (data: IAuthInfo, { rejectWithValue }) => {
        try {
            const response = await UserService.register(
                data.email,
                data.password,
                data.name
            )

            return response
        } catch (error: AxiosError | unknown) {
            if (error instanceof AxiosError) {
                return rejectWithValue(error.response?.data)
            }
        }
    }
)

const initialState: IInitialState = {
    user: {
        accessToken: '',
        email: '',
        name: '',
    },
    errorText: '',
    isError: false,
    isLoading: false,
}

export const userSlice = createSlice({
    name: 'general',
    initialState,
    reducers: {},
    extraReducers: (builder) => {
        builder.addCase(registerUser.pending, (state) => {
            state.isLoading = true
            state.errorText = ''
            state.isError = false
        })
        builder.addCase(registerUser.fulfilled, (state, action) => {
            if (action.payload) {
                state.user.accessToken = action.payload?.accessToken
                state.user.email = action.payload.user?.email
                state.user.name = action.payload.user?.name

                state.errorText = ''
                state.isError = false
                state.isLoading = false

                localStorage.setItem('token', action.payload?.accessToken)
            }
        })
        builder.addCase(registerUser.rejected, (state, action) => {
            state.errorText = action.payload as string
            state.isError = true
            state.isLoading = false
        })
    },
})

export default userSlice.reducer

I tried to pull the isError state from redux and check it, that is, if isError = false, then redirect to another page, but the problem is that isError is false by default and this check loses its significance.

I’ll repeat the question again. How do I make the redirect happen ONLY upon successful registration?

I will be glad of any advice on the topic and without. Thank you all!

How do I slide in text from a fixed position instead of left of screen?

I want to make text slide in and appear from a fixed position not the very left of the
screen. Kind of like in the website https://ctc.westpoint.edu/
So for example the text would appear 50px from the left of the page. It slides in when
the website loads.

This code is encased in a div called slogan. It contains text.

document.addEventListener('DOMContentLoaded', () => {
  const content = document.getElementById('content');
  setTimeout(() => {
    content.classList.add('visible');
  }, 1500); // Adjust the delay as needed
});
.slogan {
  display: block;
  width: 630px;
  height: 180px;
  margin: 50px;
  padding-top: 20px;
  padding-bottom: 20px;
  padding-left: 25px;
  line-height: 1.5;
  font-weight: 900;
  font-size: 45px;
  text-transform: capitalize;
  color: var(--color-4) !important;
  border-left: 3px solid #ffffff;
}

.slogan {
  position: relative;
  left: -100%;
  transition: left 0.5s ease-in;
  gap: 50px;
}

.slogan.visible {
  left: 0;
}

.slogan h1 {
  font-size: 30px;
  text-transform: capitalize;
}

.slogan p.tablet-size {
  font-weight: 900;
  color: var(--color-4);
  display: block;
  font-size: 16px;
  line-height: 1.35;
}
<div class="slogan" id="content">
  <h1>Contributing To Peace</h1>
  <p class="tablet-size">I don't provide all the answers - I want people to think for
    themselves. Want to save the world - the strategy is to affirm people as they are
    without trying to change them. Then they will treat others the same way.</p>
</div>