How to match any instance of a given url using the WebRequest API for browser extensions?

I’m trying to specify some urls to be blocked using the WebRequest API for a firefox extension.

It successfully intercepts when I type “instagram.com” in firefox address bar but the same doesn’t occur when I type “instagram.com/”. Instagram loads as it shouldn’t. I actually added "*://instagram.com/" in the urls array as a solution, but it didn’t work.

The same doesn’t occur with “example.com”. It gets blocked with or without the trailing slash.

Here’s the code which is located in a background.js file.

const urls = ["*://instagram.com/*", "*://instagram.com/", "*://example.com/*"]

browser.webRequest.onBeforeRequest.addListener(
    // Listener function
    function(details) {
        console.log("IT WENT HERE")
      // Cancel the request
      return {cancel: true};
    },
    // Filter object
    {
      urls: urls, // URLs to intercept
      types: ["main_frame"] // Type of request to intercept (e.g., main_frame for the main document)
    },
    // Additional options
    ["blocking"] // Specifies that the listener should block the request
  );

I also think I got manifest.json right (this is just a part of the file)

  "permissions": [
    "activeTab",
    "storage",
    "webRequest",
    "webRequestBlocking",
    "<all_urls>"
  ],

  "background": {
    "scripts": ["background.js"],
    "persistent":false
},

Sending an audio recording from js to an actix-web server to save to disk

Currently trying to send some recorded audio from the browser to an actix-web server, and trying to save it to disk in a manner that results in a playable track from a generic media player. I am finding this difficult to do, especially because I have never worked with media before. I am basing whatever I am doing on. a combination of some googling and some GPTing.
The problem: A file does seem to be saved to disk. It is a non-zero size file however it does not seem playable in VLC media player.
The script to send the recording to the actix-web server:

const blob = new Blob(chunks, { type: "audio/mp3" });
  const audioURL = URL.createObjectURL(blob);
  const audio = new Audio(audioURL);

  // create a button
  let button = document.createElement("BUTTON");
  // creating text to be
  //displayed on button
  let text = document.createTextNode("Play recording ", audio_rec_num + 1);
  button.appendChild(text);
  button.setAttribute("num", audio_rec_num);

  audio_rec_num++;
  document.body.appendChild(button);
  button.addEventListener("click", function () {
    let num = Number(button.getAttribute("num"));

    // audio_chunks[num].play();

    // Create FormData object to send the audio data
    const formData = new FormData();
    formData.append("audio", blob, "recorded_audio.mp3");

    // Send the audio data to the server using fetch or XMLHttpRequest
    fetch("http://127.0.0.1:8080/track_sample", {
      method: "POST",
      body: formData,
    })
      .then((response) => {
        if (response.ok) {
          console.log("Audio sent successfully");
        } else {
          console.error("Failed to send audio");
        }
      })
      .catch((error) => {
        console.error("Error sending audio: ", error);
      });
  });

The handler receiving the data:

async fn track_sampler(req_body: web::Bytes) -> impl Responder {
println!("track sampler hit");
let audio_data = req_body.to_vec();
println!("Received audio data with length: {}", audio_data.len());

// Save the audio data to a WAV file
let file_path = "received_audio.mp3";
let mut file = match File::create(file_path) {
    Ok(file) => file,
    Err(_) => return HttpResponse::InternalServerError().finish(),
};

// Write the bytes of the audio file to the file on disk
if let Err(_) = file.write_all(&audio_data) {
    return HttpResponse::InternalServerError().finish();
}
println!("done");
// Return a success response
HttpResponse::Ok().body("Audio file uploaded successfully")

}

I just need some clear pointers to be able to implement this. I don’t necessarily need code, but that could be super helpful as well. What am I doing wrong ? I know I am saving it incorrectly, but how do it ‘correctly’ ?

Note : I do not wish to save the audio to disk directly from the JS

Trying to create a 2 player game where button changes color when clicked for each user

Using Vue, firebase functions and realtime database. The ‘isPlayerTurn.value’ returns false only, it never changes. I have tried changing the values/ parameters many times, have tried using AI to suggest problems, it mostly says that the code works. It does allow the creation of matchmaking and the turn does shift between users. However the button color is never changed as the ‘isPlayerTurn.value’ doesn’t change.

<script setup>
import { ref, watchEffect, computed } from 'vue';
import { httpsCallable } from 'firebase/functions';
import { functions, realTime, auth } from '@/firebase';
import { ref as dbRef, onValue, off } from 'firebase/database';

import { onAuthStateChanged } from 'firebase/auth';

const gameId = ref('');
const playerId = ref('');
const gameTurnRef = ref('');
const isPlayerTurn = ref('');

onAuthStateChanged(auth, (user) => {
  if (user) {
    playerId.value = user.uid;
    console.log('player id:', playerId.value)
  } else {
    // Handle the case when the user is not authenticated
  }
});

const updateGameTurnRef = () => {
  if (gameId.value) {
    gameTurnRef.value = dbRef(realTime, `games/${gameId.value}/turn`);
  }
};

watchEffect(() => {
  console.log('gameId:', gameId.value);
  updateGameTurnRef();
});

watchEffect(() => {
  if (!gameTurnRef.value) return;

  const gameTurnRefListener = onValue(gameTurnRef.value, (snapshot) => {
    const turn = snapshot.val();
    console.log('turn:', turn);
    if (turn !== null) {
      isPlayerTurn.value = turn; // === playerId.value;
    } else {
      console.error('Invalid turn data:', turn);
    }
  }, (error) => {
    console.error('Error fetching turn data:', error);
  });

  return () => {
    off(gameTurnRefListener);
  };
});

const endTurn = async () => {
  try {
    const makeMove = httpsCallable(functions, "makeMove");
    const response = await makeMove(playerId.value);

    if (response.data && response.data.turn !== undefined) {
      isPlayerTurn.value = response.data.turn === playerId.value;
      console.log('is player turn:', isPlayerTurn.value);
      console.log('is response turn:', response.data.turn);
      console.log('is player :', response.data);
    }
  } catch (error) {
    console.error('Error making move:', error);
  }
};

const buttonBackgroundColor = computed(() => {
  return isPlayerTurn.value ? 'red' : 'blue';
});
</script>

<template>
  <button @click="endTurn" :style="{ backgroundColor: buttonBackgroundColor}">End Turn</button>
</template>

<style scoped>
button {
  width: 100px;
}
</style>

Firebase Function

exports.makeMove = functions.https.onCall((data, context) => {
  return new Promise((resolve, reject) => {
    try {
      assertAuth(context);

      const playerId = context.auth.uid;
      const move = data; // Expecting a string directly

      assertValidMove(move); // Validate the move

      // Check player is in a game
      RTDB.ref("matchmaking/" + playerId + "/gameId")
          .once("value")
          .then((gameIdSnapshot) => {
            const gameId = gameIdSnapshot.val();
            if (!gameId) {
              throw new functions.https
                  .HttpsError("failed-precondition", "Player is not in a game");
            }

            const gameRef = RTDB.ref("games/" + gameId);
            const playersRef = gameRef.child("gameInfo/playersInfo");
            const movesRef = gameRef.child(playerId + "/moves");
            const turnRef = gameRef.child("turn");

            // Check if it's the player's turn
            gameRef.once("value")
                .then((gameSnapshot) => {
                  const isPlayerTurn = gameSnapshot
                      .child("turn").val() === playerId;
                  if (!isPlayerTurn) {
                    throw new functions.https
                        .HttpsError("failed-precondition"
                            , "It's not your turn");
                  }

                  // Enact the player move
                  return movesRef.push().set(move)
                      .then(() => {
                        return playersRef.once("value")
                            .then((snapshot) => {
                              const players = snapshot.val();
                              const playerIds = Object.keys(players);
                              const nextTurnPlayer =
                              playerIds
                                  .find((id) => id !== playerId) ||
                                  playerIds[0];

                              // Update turn
                              return turnRef.set(nextTurnPlayer)
                                  .then(() => {
                                    // Resolve with the updated turn status
                                    resolve({turn: nextTurnPlayer ===
                                      playerId ? true : false});
                                  })
                                  .catch((error) => {
                                    reject(error);
                                  });
                            })
                            .catch((error) => {
                              reject(error);
                            });
                      })
                      .catch((error) => {
                        reject(error);
                      });
                })
                .catch((error) => {
                  reject(error);
                });
          })
          .catch((error) => {
            reject(error);
          });
    } catch (error) {
      console.error("ERROR:", error);
      reject(new functions.https.HttpsError("internal", error.message));
    }
  });
});

function assertValidMove(move) {
  // Assuming `move` is a string representing the move
  if (typeof move !== "string" || move.trim() === "") {
    throw new functions.https.HttpsError(
        "invalid-argument",
        "Move is not a valid string",
    );
  }
}

enter image description here
realtime structure

enter image description here
realtime structure ctd

I have tried switching variable properties multiple times. Thinking about the logical structure.

But I still cannot work out why it is not working.

Expecting. When one player clicks on the button the button should change to red and for the other player it should then turn to blue and vice-versa. Initially, I expect both players to have the button to be set to blue. Ideally, they should both be neutral until the sequence starts… the login stages set the initial player turn. But that is something that I am not concerned with (if anyone could solve that issue as well though then that would be amazing)

Next.js React-Leaflet bouncing marker using Leaflet.SmoothMarkerBouncing

I am new to the front-end development, I am trying to get bouncing marker in React-leaflet using
https://www.npmjs.com/package/leaflet.smooth_marker_bouncing/v/1.3.0?activeTab=explore
But I don’t have enough documentation to try it, I tried some methods based on the article
https://medium.com/sopra-steria-norge/react-leaflet-a-short-intro-with-animations-4fa8f8c5eb1c
I was able to fly to coordinates but unable to get the bouncing marker. I don’t have any errors in console as well as in terminal.
I would really appreciate if someone shared some basic implementation of the plugin in next.js and share the code.
Thanks!

Why am I getting a 404 page not found when using useRouter?

After the user submits a form, I want to redirect them to a thank you page. However, when the backend logic is processed, it redirects me to a 404 page. I checked the URL path and everything seems fine.

My project is structured like this: app -> pages -> ThankYou.tsx

Everything is happening in the FormFile.tsx which is located in the form directory inside of components.

(app -> components -> form -> FormFile.tsx )

Here is how things look:

***IMPORT STATEMENTS/ FORM SCHEMA AT THE TOP***


const FormFile = () => {   
const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      firstName: '',
      lastName: '',
      email: '',
      numberOfKids: 0
    }   })   

    const router = useRouter();   

    const onSubmit = async (values: z.infer<typeof formSchema>) => {
    try {
      console.log(values);
      const response = await axios.post('/api/formInput', values)
      router.push('/ThankYou'); //This is supposed to redirect the user to ThankYou.tsx
    } catch (error) {
      console.log(error);
    }   };

  return (
    <>
      <Form {...form}>
        <form onSubmit={form.handleSubmit(onSubmit, (errors) => console.log(errors))}>
          {/* FIRST NAME */}
          <FormField
            control={form.control}
            name="firstName"
...

Even when I enter this in the URL to test how ThankYou.tsx will look like, I get a 404…

http://localhost:3000/pages/ThankYou

Incase your wondering, this is what ThankYou.tsx looks like for now…

import React from 'react'

const ThankYou = () => {
  return (
    <div>ThankYou</div>
  )
}

export default ThankYou

Rich Text Editor, what do end users want?

I built a free, opensource Web Rich Text Editor in JavaScript and am about to go in and refactor messy code from a wild development cycle.

https://github.com/TAReber/DocyDrip
https://www.studiobriefcase.com/Tools/DocyDrip/TEO

I had some question about what just conventions about good web development practices an end user would desire because I don’t really know.

Question 1: Right now, its just creating all the paragraphs inside the content editable div element, but I thought people might prefer that each paragraph element, or list element exists inside its own div element. I could very easily do that by just updating a few small functions.

Question 2: I created a parent anchor node for the target content editable element because I thought that the UI could stay anchored to the content editable area without shifting repositioning the other elements in the DOM tree to make room for the UI.

Question 3: I added a data attribute to activate different bitwise operators to load different UI interfaces for different content editable areas. Is this safe?

Any other observations or suggestions are welcome. I know the code is a little sloppy still but I’ll be trying to address issues this next week.

The logic is structure based, it traverses the DOM tree by assuming that its been built a certain way. Once I identify how it was built, I can just run the logic through a while loop to traverse the DOM Tree.

Its all in a class, so each content editable area can have its own text editing object created just for it.

django login doesnt redirects without refresh the page

Im a frontend developer and Im working on a login page with a backend team that uses Django. in my login.html file there is a form that gets phone number and password from user. Im getting the user inputs from the from through javascript and after validation send it to backend through a fetch request. but there is a problem. the backend guy said that:”I get the phone number and password correctly through your request and redirects the page to the new url if password and phone number was true and Django redirects correctly but the browser doesnt go to the new page and I should refresh the browser. when I refresh the browser it goes to the new page correctly”.
I searched in stackoverflow and checked similar Django redirect issues but none of them was my problem. I also asked Gemini but it didnt give me any good response.
I provide both Django redirect code and my Javascript and html code:

// ================================================ from validation:

      const form = document.querySelector("form");

      const phoneRegEx = /^09d{9}$/;

      const formData = new FormData();

      form.addEventListener("submit", (event) => {
        event.preventDefault();
        const phone_value = document.querySelector(".phone").value;
        const passwordValue =                      document.querySelector(".password").value;
        document.querySelector(".phone").classList.remove("notValid");
        document.querySelector(".password").classList.remove("notValid");
        document.querySelector(".password-empty-error").style.display = "none";
        document.querySelector(".phone-empty-error").style.display = "none";
        document.querySelector(".phone-invalid-error").style.display = "none";
        if (phone_value && passwordValue) {
          if (phoneRegEx.test(phone_value)) {
            formData.append("phoneNumber", phone_value);
            formData.append("password", passwordValue);
            // for (const key of formData.keys()) {
            //     console.log(key, ":", formData.get(key));
            // }

            function getCookie(name) {
              let cookieValue = null;
              if (document.cookie && document.cookie !== "") {
                const cookies = document.cookie.split(";");
                for (let i = 0; i < cookies.length; i++) {
                  const cookie = cookies[i].trim();
                  // Does this cookie string begin with the name we want?
                  if (cookie.substring(0, name.length + 1) === name + "=") {
                    cookieValue = decodeURIComponent(
                      cookie.substring(name.length + 1)
                    );
                    break;
                  }
                }
              }
              return cookieValue;
            }
            const csrftoken = getCookie("csrftoken");
            fetch(window.location.href, {
              method: "POST",
              body: formData,
              headers: { "X-CSRFToken": csrftoken ? csrftoken : "" },
            })
              .then((response) => {
                return response.json();
              })
              .then((data) => {
                if (data.message === false) {
                  swal.fire({
                    icon: "error",
                    text: "رمز عبور اشتباه است!",
                  });
                }
              })
              .catch((err) => {});
<form action="/" method="post">
       {% csrf_token %}
       <div class="form-group">
                <input
                  placeholder="شماره موبایل"
                  class="form-control text-right phone"
                  type="text"
                  name="phone"
                />

                <small class="phone-empty-error text-danger">
                  لطفا این قسمت را خالی نگذارید
                </small>
                <small class="phone-invalid-error text-danger">
                  شماره موبایل نادرست است
                </small>
       </div>
       <div class="form-group">
                <input
                  placeholder="رمز عبور"
                  class="form-control text-right password"
                  type="password"
                  name="password"
                />

                <small class="password-empty-error text-danger">
                  لطفا این قسمت را خالی نگذارید
                </small>
        </div>
         <div class="container remember d-flex justify-content-                    between mt-3">
                <span>
                  <a class="text-dark" href="{% url 'forgot'      %}">فراموشی رمز</a>
                </span>
          </div>

              <button class="btn login-btn w-100 mt-3 mb-2"                          type="submit">
                 ورود
              </button>
             
</form>
def Login(request):

if request.method == 'POST':
    phone_number = request.POST.get('phoneNumber')
    password = request.POST.get("password")
    user = authenticate(request, username=phone_number, password=password)
    if user is not None and user.is_active:
        login(request, user)

        return redirect(reverse('eadmin'))
    return JsonResponse({'message' : False})
else:
    if request.user.is_authenticated:
        return redirect(reverse('eadmin'))

    return render(request, '../templates/login/login.html')

Why is my function returning undefined when using another function as a parameter?

Apologies if that question lacks logic. The problem I am having is with the following code:

/**
 * @param {(sentence: string) => boolean} criterion - a function that
 *  takes a sentence and returns a boolean
 * @param {string[]} sentences - an array of space-separated strings of words
 * @returns {string[]} the subset of `sentences` for which `criterion` returns true
 */
const getRelevantSentences = (about, sentences) => {
    const arr = [];
      if(about(sentences) == true){
        arr.push(sentences);
        return arr;
      }
}

This above function is supposed to take another function and an array as arguments, and then pass out an array of strings that make the function return true. In this instance, I am trying to test whether or not the specific “sentence” string within the “sentences” array makes the about() function return true. In other words, I am returning any strings that are “similar” to that of another string.

Below is the code that makes up the about() function.

/**
 * @param {string[]} topics - an array of topic words
 * @param {string} sentence - a space-separated string of words
 * @returns {boolean} whether `sentence` contains any of the words in `topics`
 */
const isRelevant = (topics, sentence) => {
  for(i=0; i<topics.length;i++){
    if (sentence.includes(topics[i])) {
      return true;
    }
    else {
      return false;
    }
  }
};

/**
 * @param {string[]} topics - an array of topic words
 * @returns {(sentence: string) => boolean} a function that takes a sentence
 *  and returns whether it is relevant to `topics`
 */
const about = (topics) => {
    return function(sentence) {
      return isRelevant(topics,sentence);
    }
};

For intents and purposes the data used as input is:

const sentence = "the quick brown fox jumps over the lazy dog"

const sentences = "I have a pet dog", "I have a pet cat", "I don't have any pets"

If you all require any more data please let me know. Any help is greatly appreciated! Thank you.

Linking CSS and JS to a HTML page using Thymeleaf in a Spring Boot application and Docker

I’m trying to do a quite simple thing: adding a stylesheet .css file and a .js file to my html page called: “scalata.html” but everytime I get these errors:

GET https://my-domain.app/css/scalata.css 404 (Not Found)

GET https://my-domain.app/js/scalata.js net::ERR_ABORTED 404 (Not Found)

First of all, in my pom.xml file, I have added these lines in order to correctly setup ThymeLeaf into my Spring Boot project:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

This is my “scalata.html”:

<!DOCTYPE html>

<!--Adding Thymeleaf-->
<html lang ="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <!--Enabling proper responsive behavior-->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>My Game</title>

    <link href="../static/css/scalata.css" th:href="@{/css/scalata.css}" rel="stylesheet" />

    <script src="../static/js/scalata.js" th:src="@{/js/scalata.js}"></script>
    

Could you help me?

I tried this: Where to put static files such as CSS in a spring-boot project? and this: Linking CSS to HTML view using Thymeleaf

Jquery dialog unable to remove divs after close

I have a JQuery dialog which takes input from TextArea and responds back from Ajax request and response
I added the request and responses back to form using a div with images. But problem is with the removing of divs after dialog close. I have used remove methods, still it did not work.

Am I doing anything wrong here.
enter image description here
Coded as below:
function openHelpDialog(a) {

document.getElementById("helpDialog").style.display = "block";

document.getElementById("helpForm").style.display="flex";
var $loading = $('#loader').hide();

$("#helpDialog").dialog({
    modal: true,
    width: 350,
    zIndex: 9999,   
    buttons: {
        "Send": function() {
             var formData = new FormData();
                formData.append("hpQuestion", $("#usermsg").val());
                
                $.ajax({
                    type: "POST",
                    url: "submitQuestion.htm",
                    data: formData,
                    contentType: false,
                    processData: false,

                    beforeSend: function() {
                        $('#loader').show();

                        
                        $('<div id="req"  style="display: inline-flex;"> <img src="static/img/global/guy1.png" alt=""/><div class="reqres">' + $("#usermsg").val()+'</div></div>').insertBefore('#usermsg');
                        
        jQuery('.ui-dialog button:nth-child(1)').button('disable');                     
                        
                        document.getElementById('usermsg').setAttribute("disabled", "disabled");
                        $("#usermsg").val("");
                    },
                    success: function(responseMessage) {
                        
                        $('<div id="res"  style="display: inline-flex;"> <img src="static/img/global/bot2.png" alt=""/><div class="reqres">' + responseMessage+'</div></div>').insertBefore('#usermsg');

                        
                        $("#usermsg").val("");
                    },
                    complete: function() {
                        $('#loader').hide();
                        jQuery('.ui-dialog button:nth-child(1)').button('enable');
                        document.getElementById('usermsg').removeAttribute("disabled");
                        $("#usermsg").val("");
                    },
                    error: function(error) {
                        customAlert("Error submitting the Question: " + error.responseText);
                    }
                });
                
            }
            }
            },  
    close: function() {
        
        $('req').remove();

$(‘res’).remove();

        document.getElementById("helpForm").style.display="none";
        $("#usermsg").val("");
        $(this).dialog("destroy");
        
    }

}).dialog("widget").find(".ui-dialog-title").text('Ask a question'); 
$(".ui-dialog-titlebar:not(.image-already-added)").prepend("<img style='float: left;'src='static/img/global/chatbotD.png'/>" + "Ask CFA").addClass("image-already-added");

}

I tried with both $(‘req’).remove();$(‘res’).remove(); and $(‘req’).remove(‘.reqres’);
$(‘res’).remove(‘.reqres’);, but did not work.
Expecting to remove the divs after close

TypeError in Tanstack Query React

I am new to react tanstack query and I am building a todo list app to reinforce the concepts that I am learning. The todos are coming from DummyJson API -https://dummyjson.com/docs/todos. The response data object has a few properties – limit, skip, total and an array of todos as defined in types/index.ts.

// types/index.ts
export type TodoType = {
    id: number;
    completed: boolean;
    todo: string;
    userId: number;
};

export type TodosType = {
    limit: number;
    skip: number;
    total: number;
    todos: TodoType[]; // Correctly defined as an array of Todo objects
};

In my lib folder, I have a react-query file.

// lib/react.query.ts
import { QueryClient, DefaultOptions } from '@tanstack/react-query';

const queryConfig: DefaultOptions = {
  queries: {
    refetchOnWindowFocus: false,
  },
};

export const queryClient = new QueryClient({ defaultOptions: queryConfig });

Which is being used in my api folder.

// api/getTodos.ts
import { useQuery } from '@tanstack/react-query';
import { axios } from '../lib/axios';
import { TodoType  } from '../types';

export const getTodos = (): Promise<TodoType[]> => {
  return axios.get('/todos');
}; 

export const useTodos = () => {
    return useQuery({queryKey: ['todos'], queryFn: () => getTodos()});
};

The issue is that in my TodoWrapper where I am utilising this useTodos hook, in the console.log,I get the typescript error Property 'todos' does not exist on type 'TodoType[]'.Which is strange beacuse I’m sure that todos does exist in TodoType.

export const TodoWrapper = () => {
  const todosQuery = useTodos();

  if(todosQuery.isLoading) return <div>Loading...</div>

  if(!todosQuery.data) return null;

console.log(todosQuery.data.todos);

}

How can i print a receipt in a thermal printer in one click without a dialog box

I’m developing the management part of a delivery system and i am trying to generate a and print in a thermal printer the customers asks. Most of the users will be restaurants, so i wish i could print it without those dialog boxes just when i click in a button to ‘print’ to avoid an exausting work when they have a lot of asks.

I can generate the pdf correctly, but it is not printing right. Thats what i’ve tryied:

function Relatorio(props){

useEffect(() => {
    const element = document.getElementById('wrap-relatorio-pedido'); 
    const opt = {
        margin: 5,
        filename: `pedido #${props.nbl_num_nota}.pdf`,
        image: { type: 'jpeg', quality: 0.98 },
        html2canvas: { scale: 2 },
        jsPDF: { unit: 'mm', format: 'a6', orientation: 'portrait' }
    };

    //first attempt
    // html2pdf().from(element).set(opt).outputPdf('arraybuffer').then((pdf) => {
    //     const blob = new Blob([pdf], { type: 'application/pdf' });
    //     const blobUrl = URL.createObjectURL(blob);

    //     const iframe = document.createElement('iframe');
    //     iframe.style.display = 'none';
    //     iframe.src = blobUrl;
    //     document.body.appendChild(iframe);

    //     iframe.onload = () => {
    //         iframe.contentWindow.print();
    //         document.body.removeChild(iframe);
    //         URL.revokeObjectURL(blobUrl);
    //     };
    // });
    
    
    //second attempt
    // var req = new XMLHttpRequest();
    // req.onload = function (event) {
    //     var blob = new Blob([req.response], {type: 'application/pdf'}); //this make the magic
    //     var blobURL = URL.createObjectURL(blob);
    
    //     const iframe =  document.createElement('iframe'); //load content in an iframe to print later
    //     document.body.appendChild(iframe);
    
    //     iframe.style.display = 'none';
    //     iframe.src = blobURL;
    //     iframe.onload = function() {
    //       setTimeout(function() {
    //         iframe.focus();
    //         iframe.contentWindow.print();
    //       }, 1);
    //     };
    // };

    html2pdf().from(element).set(opt).save();

}, [props.nbl_num_nota]);

const space = ' '; // adiciona espaçamento em spans

const data = new Date(props.nbl_dat_emissao);

// Formatar a data no formato dd/mm/yyyy
const dataFormatada = `${('0' + data.getDate()).slice(-2)}/${('0' + (data.getMonth() + 1)).slice(-2)}/${data.getFullYear()}`;

// Formatar a hora no formato hh:mm
const horaFormatada = `${('0' + data.getHours()).slice(-2)}:${('0' + data.getMinutes()).slice(-2)}`;

return <>
    <div className='d-flex justify-content-between pedido ps-2 pt-3 pb-1' id='body-relatorio-pedido'>
        <div className='row pt-4' id='wrap-relatorio-pedido'>
            //content
        </div>
    </div>
</>
}

export default Relatorio;

I don’t know if it is possible due to the browser security and i have alredy tryied to the other similar question’s solutions… so if anyone know how to do it or can answer if it is possible or not would help a lot.

Why an HTML/ JS Button is working on PC browser but not on mobile devices?

I am developing a django web app, and I have a particular button which is for purchasing a subscription through stripe. the button is working fine on PC and desktop browsers, but not on mobile devices (Iphones). I tried to enable pop-ups, but it didn’t work. this is the code below:

<style>
    .subscription-container {
      display: flex;
      justify-content: space-around;
      margin-bottom: 20px;
    }

        @media screen and (max-width: 768px) {
      .subscription-container {
        flex-direction: column;

      }
    }
  </style>
  <script>
    console.log("Sanity check!");

    // Get Stripe publishable key
    fetch("/sciences/config/")
      .then((result) => { return result.json(); })
      .then((data) => {
        // Initialize Stripe.js
        const stripe = Stripe(data.publicKey);

        // Event handler for 14-day subscription
        document.querySelector("#submitBtn14").addEventListener("click", () => {
          // Get Checkout Session ID for 14-day subscription
          fetch("/sciences/create-checkout-session/")
            .then((result) => { return result.json(); })
            .then((data) => {
              console.log(data);
              // Redirect to Stripe Checkout
              return stripe.redirectToCheckout({sessionId: data.sessionId_14day})
            })
            .then((res) => {
              console.log(res);
            });
        });

        // Event handler for 1-day subscription
        document.querySelector("#submitBtn1").addEventListener("click", () => {
          // Get Checkout Session ID for 1-day subscription
          fetch("/sciences/create-checkout-session/")
            .then((result) => { return result.json(); })
            .then((data) => {
              console.log(data);
              // Redirect to Stripe Checkout
              return stripe.redirectToCheckout({sessionId: data.sessionId_1day})
            })
            .then((res) => {
              console.log(res);
            });
        });
      });
  </script>
</head>
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Django + Stripe Checkout</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css">
  <script src="https://js.stripe.com/v3/"></script>
  <script defer src="https://use.fontawesome.com/releases/v6.4.0/js/all.js"></script>
<body>
<section class="section">
  <div class="container">
    <center>
  <div class="subscription-container">
      <div style="width: 100%; max-width: 400px; background-color: rgba(58, 134, 183, 0); padding: 20px; border: 15px groove rgba(255, 255, 255, 0.0); box-shadow: 0 6px 6px rgba(0, 0, 0, 0.1); border-radius: 10px; ">

        <h2 style="font-weight: 700; font-size: 2.5rem;">14-Day Unlimited Subscription</h2>
          <p style="font-size: 11px;">Create and edit today</p>
          <h3 style="font-weight: 700; font-size: 3.75rem;">$ 7.50</h3>
          <p style="padding: 10px;">-Unlimited Edits<br>-Unlimited Template Changes<br>-Use Of Chatbots<br>-Quick Customer Support</p>
          <button class="button is-primary" id="submitBtn1">Purchase 14-Day Subscription</button>

      </div>

      <div style="width: 100%; max-width: 400px; background-color: rgba(58, 134, 183, 0); padding: 20px; border: 15px groove rgba(255, 255, 255, 0.0); box-shadow: 0 6px 6px rgba(0, 0, 0, 0.1); border-radius: 10px;">
        <div style="margin-bottom: 20px;">
          <h2 style="font-weight: 700; font-size: 2.5rem;">1-Day Unlimited Subscription</h2>
          <p style="font-size: 11px;">Create and edit a perfect</p>
          <h3 style="font-weight: 700; font-size: 3.75rem;">$ 2.25</h3>
          <p style="padding: 10px;">-Unlimited Edits<br>-Unlimited Template Changes<br>-Use Of Chatbots<br>-Quick Customer Support</p>
          <button class="button is-primary" id="submitBtn14">Purchase 1-DAY Subscription</button>
        </div>
      </div>
  </div>
     </center>
  </div>
</section>
</body>
</html>

Please help let me know why the buttons are working on PC but not on mobile device browsers because i’ve tried enabling pop-ups and cookies but it still doesnt work.

why props obj still exists in memory after component unmounted?

Ho could prop object exists in memory even after component unmounted

const myObj = {....}
<parent>
   <child myObj = {myObj}>
      ...
   </child>
</parent>

once both parent and child unmounted I still see myObj allocated in memory when I do snapshots comparison in Google Dev Tool…

and every time component mounts I allocates more.
So how properly prevent this kind of memory leak and kill props obj in memory?