Difference between http and express

I’m trying to build a socket.io based application and I can’t seem to get the difference between http and express.

import express from 'express';
import http from 'http';
import {Server} from 'socket.io';

const app=express();
const server = http.createServer(app); 
const io=new Server(server,{
    cors:{
        origin:"http://localhost:3001"
    }
});

Why do I need http when it has the same functionality as express?
Could anyone explain this code?

How can I properly implement refresh token handling on the frontend in a React application?

So I have been trying to create a fullstack app that uses both an Access Token and refresh token, I have had success in past occassion with implementing access tokens but with refresh tokens I’m really struggling.

To give you some context: I have been working on the backend of the app and I have come up with:

//Tokens send with the login of the user:

 const accessToken = jwt.sign(
      {
        userId: foundUsername.rows[0].id_persona,
        username: foundUsername.rows[0].username,
        roles: foundRoles.rows,
      },
      process.env.JWT_SECRET_KEY as string,
      { expiresIn: "5m" }
    );

    const refreshToken = jwt.sign(
      {
        userId: foundUsername.rows[0].id_persona,
        username: foundUsername.rows[0].username,
      },
      process.env.JWT_SECRET_KEY as string,
      {
        expiresIn: "1d",
      }
    );

    res.cookie("refresh_cookie", refreshToken, {
      httpOnly: true,
      secure: false,
      sameSite: "none",
      maxAge: 24 * 60 * 60 * 1000,
    }); 
return res.json({ accessToken });

Now if I am not mistaken the refresh token is supposed to be holded in a local storage while the Refresh one is supposed to be the “cookie”.

this is the refresh the “access token” when asked to endpoint:

export const refreshAccess = async (req: Request, res: Response) => {
  // Check if the token exists
  const token = req.cookies["refresh_token"];
  if (!token) {
    return res.status(401).json({ message: "Unauthorized" });
  }

  try {
    const decoded = jwt.verify(
      token,
      process.env.JWT_SECRET_KEY as string
    ) as JwtPayload;
    const result = await pool.query(
      "SELECT id_roles FROM assignated_roles WHERE id_persona = $1",
      [decoded.userId]
    );

    const foundRoles = result.rows.map((row) => row.id_roles);
    const accessToken = jwt.sign(
      {
        userId: decoded.userId,
        username: decoded.username,
        roles: foundRoles,
      },
      process.env.JWT_SECRET_KEY as string,
      { expiresIn: "5m" }
    );

    return res.json({ accessToken });

I am satisfied with these Endpoints. I have tested them and they work… in theory.
But here come my big questions that I have been asking myself before even finishing my login.

How am I supposed to reach these endpoints? I was inspired to create and use Refresh/Access token becouse of this post: https://designtechworld.medium.com/how-to-authenticate-using-access-and-refresh-tokens-using-react-js-57756df2d282

Now in said post the way the Access Token is being refreshed its through a timer… That.. Can’t be right no? I was thinking about holding the data in a context so I could make protected Routes later on. But in order to do so. I would have to constantly make requests with each click the user make. So I would be constantly asking the DB for information. Which again doesn’t seem right.

As you might have noticed I feel frozen becouse I have so many ways I feel like this could be implemented.

I would like some guidance as to what are best practices when it comes to the implementation of Refresh/Access tokens when it comes to the frontend(React).

With that being said, any feedback on how to properly create a working frontend would be really appreciated.

Thank you for your time!

is there a node package tailored for high-fidelity conversion from doc to html5 code?

I’m developing a NEXTjs app that allows user to view their docx files in the browser, the goal is to convert the file from word to html code with proper formatting, ps: html should not be editable

Im currently using mammoth.js but it doesn’t seems to be working below is the component

export default function Home() {
  const [htmlContent, setHtmlContent] = useState("");

  const handleFileUpload = async (event) => {
    const file = event.target.files[0];
    if (
      file &&
      file.type ===
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
    ) {
        const reader = new FileReader();
        reader.onload = async (e) => {
          const arrayBuffer = e.target.result;
          const options = {
            styleMap: [
              "p.Heading1 => h1",
              "p.Heading2 => h2",
              "p.Heading3 => h3",
              "p.Heading4 => h4",
              "p.Heading5 => h5",
              "p.Heading6 => h6",
              "p[style-name='Title'] => h1.title",
              "p[style-name='Subtitle'] => h2.subtitle",
              "p[style-name='Quote'] => blockquote",
              "table => table.table-bordered",
              "p => p.paragraph",
              "r[style-name='Bold'] => strong",
              "r[style-name='Italic'] => em",
            ],
            convertImage: mammoth.images.imgElement((image) => {
              return image.read("base64").then((imageBuffer) => {
                return {
                  src: "data:" + image.contentType + ";base64," + imageBuffer,
                };
              });
            }),
          };
          const result = await mammoth.convertToHtml(
            { arrayBuffer },
            options
          );
          setHtmlContent(result.value);
        };
        reader.readAsArrayBuffer(file);
      } catch (error) {
        console.error(error);
      }
  };

  const handleSaveHtml = () => {
    const blob = new Blob([htmlContent], { type: "text/html;charset=utf-8" });
    saveAs(blob, "converted-document.html");
  };

  return (
    <>
      <main className={styles.main}>
        <input type="file" onChange={handleFileUpload} accept=".docx" />
        {htmlContent && (
          <div>
            <h2>Converted HTML:</h2>
            <div
              dangerouslySetInnerHTML={{ __html: htmlContent }}
              style={{
                backgroundColor: "#fff",
                color: "#000",
                padding: "20px",
                borderRadius: "8px",
                lineHeight: "1.6",
                fontFamily: "Arial, sans-serif",
              }}
            />
            <button onClick={handleSaveHtml} style={{ marginTop: "20px" }}>
              Save HTML
            </button>
          </div>
        )}
      </main>
    </>
  );
}

Issue:
The problem is that when I upload a .docx file, the conversion does not work as expected. The HTML output is either not rendered at all or rendered incorrectly. There are no specific errors in the console, but the document’s content is not being displayed properly in the browser.

What I’ve Tried:
I’ve ensured that the file being uploaded is a valid .docx file.
I’ve verified that the file type is correctly identified as “application/vnd.openxmlformats-officedocument.wordprocessingml.document”.

I’ve tried adjusting the styleMap to ensure proper mapping of Word styles to HTML elements.
I’ve checked the browser console for any errors, but nothing significant shows up.

Environment:
Next.js version: 14.2.5
mammoth.js version: 1.4.2
file-saver version: 2.0.5
Browser: Chrome 104

Question:
What could be causing mammoth.js to fail in converting the DOCX file to HTML properly, and how can I fix this issue to ensure that the HTML is rendered correctly in the browser?

Add functionality to ajax_add_to_cart button in woocommerce to close a custom modal after item was added to cart

Im trying to close a modal with javascript (doesnt matter if its with js or jquery or php), I’ve tried adding custom JS with a button pointer like this:

<script type="text/javascript">
(function($){
   $('.btn[data-product_id='11068651']').click( function(){
      document.querySelector(".speak-up-modal").style.display = "none";
   });
   $('.btn[data-product_id='11068652']').click( function(){
      document.querySelector(".speak-up-modal").style.display = "none";
   });
})(jQuery);
</script>

And add this to the wp_footer this way:

add_action( 'wp_footer', 'single_add_to_cart_event_button_function' );
function single_add_to_cart_event_button_function() {
    ?>
        <script type="text/javascript">
            (function($){
                $('.btn[data-product_id='11068651']').click( function(){
                    document.querySelector(".speak-up-modal").style.display = "none";
                });
                $('.btn[data-product_id='11068652']').click( function(){
                    document.querySelector(".speak-up-modal").style.display = "none";
                });
            })(jQuery);
        </script>
    <?php
}

But nothing works, this is how Im using the woocommerce buttons in the modal:

<a href="#" class="button add_to_cart_button ajax_add_to_cart btn" data-product_id="11068652" data-quantity="1" rel="nofollow">

And nothing I do adds the event to the button, any chance for some help in modifying/adding functionality to this button?

This is what I’ve tried:
Button:

<a href="#" class="button add_to_cart_button ajax_add_to_cart btn" data-product_id="11068652" data-quantity="1" rel="nofollow">

Inside the JS in footer itself where I initiate the modal

<script type="text/javascript">
(function($){
   $('.btn[data-product_id='11068651']').click( function(){
      document.querySelector(".speak-up-modal").style.display = "none";
   });
   $('.btn[data-product_id='11068652']').click( function(){
      document.querySelector(".speak-up-modal").style.display = "none";
   });
})(jQuery);
</script>

And in functions.php:

add_action( 'wp_footer', 'single_add_to_cart_event_button_function' );
function single_add_to_cart_event_button_function() {
    ?>
        <script type="text/javascript">
            (function($){
                $('.btn[data-product_id='11068651']').click( function(){
                    document.querySelector(".speak-up-modal").style.display = "none";
                });
                $('.btn[data-product_id='11068652']').click( function(){
                    document.querySelector(".speak-up-modal").style.display = "none";
                });
            })(jQuery);
        </script>
    <?php
}

Generating TOTP using OTPAuth library on Nodejs

I do face some problem while generating TOTP by OTPAuth library on Nodejs. Sometimes, time on my devices is not correct, so it led to the incorrect in TOTP generated. I can prevent it by set the right time for my device.

I wonder do we have any way to make sure that the OTPAuth library generate based on the correct time not by manually set time on device?

How can I edit the Date format? [duplicate]

I have an application which can be used to organize exams. There is a span to demonstrate registration date. Here is how I did it:

let getDate = new Date();

But the thing is it shows whole information about time but I only need date and month. E.g. 12 March.

So can you please suggest any method or piece of code to do this?

The useEffect hook in React does not render all changes on Safari

I’m trying to write a web game with WebSocket synchronization. In my React app, I receive updates via WebSocket to update the view of the application. My problem is that when I receive multiple messages successively, my useEffect only considers the last one. I think this is due to an optimization in React. My code works well on Chrome, but it doesn’t work in Safari. How can I fix this?

Code:

const { message, sendMessage, setUrl } = useWebSocket();
useEffect(() => {
    console.log(message);
    if (message && sessionJeu != true) {
      setSessionJeu(true);
    }

    if (message.type == "end") {
      setSessionJeu(false);
    }
  }, [message]);

Logs:

My logs on safari

You can see what my WebSocket hook prints first and what the useEffect prints at the last line.

My code works in Chrome, so I’m sure that the error is in this part.

If necessary, I can provide more information. I hope this is clear.

IsNumeric function is not working when the value is “0”

I have this JavaScript function in my Razor page to check if the value is numeric.

When a “0” is passed to this function, it will return as false. I have tested the expression in other RegEx tester and “0” is a valid match. If the input parameter is “0.0”, it will be ok.

Any idea what went wrong? Please advise. Thanks.

function isNumericValid(value) {
  var result = false;
  if (value != "") {
    // up to 12 digits and 10 dec places
    let template = /^-{0,1}d{1,12}(.d{1,10})?$/;

    if (template.test(value))
      result = true;
  }
  return result;
}

console.log(isNumericValid("0"))
console.log(isNumericValid(0))
console.log(isNumericValid("0.0"))
console.log(isNumericValid(0.0))
console.log(isNumericValid(1234.10))

How to get user regional settings in a browser? Not user language

My Windows11 language is english but my regional settings is set to danish.

When I run the below code ‘en-GB’ is returned. I expected ‘da-DK’ to be returned.

    function getUserLocale() {
        const intl = window.Intl;
        if (intl !== undefined) {
            return intl.NumberFormat().resolvedOptions().locale;
        }

        // Old standard.
        return navigator.language ?? "en-US";
    }

Lodash how to sort a group with custom sequence?

Currently the response that are being sent back to client side looks like this:

[
  {
    "categoryName": "Orders",
    "categorySettings": ...the rest
  },
  {
    "categoryName": "Notifications",
    "categorySettings": ...the rest
  },
  {
    "categoryName": "Personalisation",
    "categorySettings": ...the rest
  }
]

However, the expected layout is:

[
  {
    "categoryName": "Personalisation",
    "categorySettings": ...the rest
  },
  {
    "categoryName": "Notifications",
    "categorySettings": ...the rest
  },
  {
    "categoryName": "Orders",
    "categorySettings": ...the rest
  }
]

How do I sort the categoryName to match the order that I expected? I am thinking about matching the sort order to an array of object with “categoryName” and “sequence” properties, but I am stuck at the code.

My current code is as below:

const groupedData = _.chain(allData)
      .groupBy('sectionName')
      .map((allData, sectionName) => ({
        categoryName: sectionName,
        categorySettings: _.chain(allData)
          .groupBy('group')
          .map((groupSettings, group) => ({
            group: group,
            groupSettings: _.chain(groupSettings)
              .sortBy('ordering')
              .groupBy('title')
              .map((titleSettings, title) => ({
                settingName: title,
                settingDescription: titleSettings[0].description,
                settingInputs: _.map(titleSettings, ({name, value, inputSetting}) => ({
                  inputName: name,
                  inputValue: value,
                  inputConfig: inputSetting,
                })),
              }))
              .value(),
          }))
          .value(),
      }))
      .value();

how can I open up a popup screen? (javascript/python)

I am writing a javascript code with python.

final_html_code = ""
open_popup_script1 = """
<script type='text/javascript'>
var existingPopup;

function openPopup1(links, titles) { 
    if (existingPopup) {
        existingPopup.close();
    }
    existingPopup = window.open('', '_blank', 'left=20,top=20,width=500,height=300,toolbar=1,resizable=0');
    for (var i = 0; i < links.length; i++) {
        existingPopup.document.write('<p><a href="' + links[i] + '" target="_blank" style="font-size: 12px;">' + titles[i] + '</a></p>');
    }
}
</script>
"""

for category in categories:
    df = pd.read_excel(f"C:/Users/U017831/trash/2024-08-09_{category}_뉴스키워드.xlsx")
    html_header = f"""
<html>
<body>
{open_popup_script1}
<div style="display: flex; flex-direction: column; align-items: center; width:380px; height:380px;
background-color:#f2f2f2; position:relative;"> 
"""
    html_footer = f"""
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<h2 style="font-size: 15px; color:rgba(0,0,0,0);">{category} 신규어&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</h2><br>
</div>
"""
    
    html_codes = [ 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:50%; left:50%; 
transform:translate(-50%, -50%); font-size:19px; color:rgb(0, 0, 128); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""", 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:20%; left:23%; 
transform:translate(-50%, -50%); font-size:18px; color:rgb(0, 0, 128); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""",
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:90%; left:23%; 
transform:translate(-50%, -50%); font-size:17px; color:rgb(0, 0, 128); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:93%; left:75%; 
transform:translate(-50%, -50%); font-size:17px; color:rgb(70, 130, 180); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:75%; left:28%; 
transform:translate(-50%, -50%); font-size:16px; color:rgb(70, 130, 180); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:60%; left:19%; 
transform:translate(-50%, -50%); font-size:16px; color:rgb(70, 130, 180); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:60%; left:80%; 
transform:translate(-50%, -50%); font-size:16px; color:rgb(70, 130, 180); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:40%; left:25%; 
transform:translate(-50%, -50%); font-size:15px; color:rgb(70, 130, 180); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:80%; left:70%; 
transform:translate(-50%, -50%); font-size:15px; color:rgb(70, 130, 180); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:66%; left:48%; 
transform:translate(-50%, -50%); font-size:15px; color:rgb(70, 130, 180); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}},{{titles}}); return false;' style="position:absolute; top:25%; left:55%; 
transform:translate(-50%, -50%); font-size:14px; color:rgb(70, 130, 180); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:10%; left:80%; 
transform:translate(-50%, -50%); font-size:14px; color:rgb(70, 130, 180); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:14%; left:20%; 
transform:translate(-50%, -50%); font-size:14px; color:rgb(150, 206, 280); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:85%; left:50%; 
transform:translate(-50%, -50%); font-size:14px; color:rgb(90, 100, 200); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:20%; left:75%; 
transform:translate(-50%, -50%); font-size:14px; color:rgb(135, 206, 235); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:7%; left:29%; 
transform:translate(-50%, -50%); font-size:13px; color:rgb(135, 206, 235); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:35%; left:80%; 
transform:translate(-50%, -50%); font-size:13px; color:rgb(135, 206, 235); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:13%; left:55%; 
transform:translate(-50%, -50%); font-size:13px; color:rgb(135, 206, 235); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:70%; left:78%; 
transform:translate(-50%, -50%); font-size:13px; color:rgb(107, 142, 35); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:45%; left:78%; 
transform:translate(-50%, -50%); font-size:13px; color:rgb(107, 142, 35); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:30%; left:13%; 
transform:translate(-50%, -50%); font-size:12px; color:rgb(107, 142, 35); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:40%; left:65%; 
transform:translate(-50%, -50%); font-size:12px; color:rgb(107, 142, 35); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup3({{links}}, {{titles}}); return false;' style="position:absolute; top:26%; left:85%; 
transform:translate(-50%, -50%); font-size:11px; color:rgb(107, 142, 35); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:5%; left:62%; 
transform:translate(-50%, -50%); font-size:11px; color:rgb(107, 142, 35); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:97%; left:41%; 
transform:translate(-50%, -50%); font-size:10px; color:rgb(107, 142, 35); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:47%; left:17%; 
transform:translate(-50%, -50%); font-size:10px; color:rgb(0, 100, 0); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:80%; left:16%; 
transform:translate(-50%, -50%); font-size:10px; color:rgb(0, 128, 0); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:10%; left:42%; 
transform:translate(-50%, -50%); font-size:10px; color:rgb(0, 128, 0); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:66%; left:70%; 
transform:translate(-50%, -50%); font-size:10px; color:rgb(0, 128, 0); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:76%; left:85%; 
transform:translate(-50%, -50%); font-size:10px; color:rgb(51,153,153); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
 f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:73%; left:55%; 
transform:translate(-50%, -50%); font-size:10px; color:rgb(51,153,153); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
 f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:44%; left:48%; 
transform:translate(-50%, -50%); font-size:10px; color:rgb(51,153,153); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:98%; left:77%; 
transform:translate(-50%, -50%); font-size:10px; color:rgb(51,153,153); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,    
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:98%; left:15%; 
transform:translate(-50%, -50%); font-size:10px; color:rgb(51,153,153); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:3%; left:20%; 
transform:translate(-50%, -50%); font-size:10px; color:rgb(51,153,153); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:25%; left:30%; 
transform:translate(-50%, -50%); font-size:10px; color:rgb(51,153,153); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:33%; left:32%; 
transform:translate(-50%, -50%); font-size:10px; color:rgb(107, 142, 35); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:36%; left:21%; 
transform:translate(-50%, -50%); font-size:10px; color:rgb(51,153,153); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:70%; left:20%; 
transform:translate(-50%, -50%); font-size:10px; color:rgb(51,153,153); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:57%; left:50%; 
transform:translate(-50%, -50%); font-size:10px; color:rgb(51,153,153); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:53%; left:19%; 
transform:translate(-50%, -50%); font-size:10px; color:rgb(51,153,153); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:50%; left:80%; 
transform:translate(-50%, -50%); font-size:9px; color:rgb(107, 142, 35); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:86%; left:80%; 
transform:translate(-50%, -50%); font-size:9px; color:rgb(107, 142, 35); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:83%; left:19%; 
transform:translate(-50%, -50%); font-size:9px; color:rgb(70, 130, 180); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:55%; left:85%; 
transform:translate(-50%, -50%); font-size:9px; color:rgb(51,153,153); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:3%; left:47%; 
transform:translate(-50%, -50%); font-size:9px; color:rgb(70, 130, 180); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:78%; left:45%; 
transform:translate(-50%, -50%); font-size:9px; color:rgb(70, 130, 180); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:30%; left:75%; 
transform:translate(-50%, -50%); font-size:9px; color:rgb(107, 142, 35); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:67%; left:20%; 
transform:translate(-50%, -50%); font-size:9px; color:rgb(107, 142, 35); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" ,
f"""<a href="#" onclick='openPopup1({{links}}, {{titles}}); return false;' style="position:absolute; top:14%; left:80%; 
transform:translate(-50%, -50%); font-size:9px; color:rgb(107, 142, 35); font-weight:bold; text-decoration:none; 
white-space:nowrap;">{{word}}</a>""" , 
    ]
    modified_html_codes = []
    i = 0 
    count=0
    df['keyword'].fillna(method='ffill', inplace=True)
    unique_keywords = df['keyword'].unique()[:50]

    for word in unique_keywords:
        if pd.isnull(word) or word.strip() == '':
            continue

        related_rows = df[df['keyword'] == word]
        links = related_rows['link'].tolist()
        titles = related_rows['title'].apply(lambda x: x.replace('"',"").replace("'","")).tolist()

        html_code = html_codes[i]
        modified_html_codes.append(html_code.format(word=word, links=json.dumps(links), titles=json.dumps(titles)))

        i += 1

    category_html_code = html_header + "n".join(modified_html_codes)  + html_footer
    final_html_code+=category_html_code

final_html_code = f"""
<html>
<body>
<div style="display: flex; flex-direction: row; justify-content: space-around; width:1200px; height:380px;">
{final_html_code}
</div>
"""

I want to open up a new popup screen by clicking the title. But the thing is, when I click the title the link opens in a new tab, not in a form of a popup screen. Just wanna know what’s wrong with the code.

to sum up, I want to open a popup from a popup.

I wanted the link to open up in a form of a popup, not in a form of a full-screen tab. So I used ‘_blank’ but it didn’t work.

Why is the player getting damaged whenever either the bullet despawns or the player gets hit?

I have other code to go with this, but whenever a bullet despawns (hits the edge or times out), the player gets damaged. I haven’t been able to test if the player gets damaged when they collide because of how much damage is done passively.

function shootPlayer() {
    if (!document.body.contains(enemy)) return;  // Stop if the enemy is removed

    const playerRect = player.getBoundingClientRect();
    const playerCenterX = playerRect.left + playerRect.width / 2;
    const playerCenterY = playerRect.top + playerRect.height / 2;
    const enemyRect = enemy.getBoundingClientRect();
    const enemyCenterX = enemyRect.left + enemyRect.width / 2;
    const enemyCenterY = enemyRect.top + enemyRect.height / 2;

    const angle = Math.atan2(playerCenterY - enemyCenterY, playerCenterX - enemyCenterX);

    const bullet = document.createElement('div');
    bullet.className = 'bullet';
    bullet.style.position = 'absolute';
    bullet.style.top = `${enemyCenterY}px`;
    bullet.style.left = `${enemyCenterX}px`;
    document.body.appendChild(bullet);

    const bulletSpeed = 5;
    const bulletDamage = 5;

    function moveBullet() {
        let bulletTop = parseFloat(bullet.style.top);
        let bulletLeft = parseFloat(bullet.style.left);

        bulletTop += bulletSpeed * Math.sin(angle);
        bulletLeft += bulletSpeed * Math.cos(angle);

        bullet.style.top = `${bulletTop}px`;
        bullet.style.left = `${bulletLeft}px`;

        console.log(`Bullet Position: (${bulletLeft}, ${bulletTop})`);

        // Simple collision detection with the player
        if (
            bulletLeft >= playerRect.left &&
            bulletLeft <= playerRect.right &&
            bulletTop >= playerRect.top &&
            bulletTop <= playerRect.bottom
        ) {
            decreasePlayerHealth(bulletDamage);
            bullet.remove();
            console.log('Bullet hit the player.');
            return;
        }

        // Check if the bullet is out of bounds and remove it
        if (bulletTop < 0 || bulletTop > window.innerHeight || bulletLeft < 0 || bulletLeft > window.innerWidth) {
            bullet.remove();
            console.log('Bullet despawned.');
            return;
        }

        // Continue moving the bullet
        requestAnimationFrame(moveBullet);
    }

    requestAnimationFrame(moveBullet);
}

I’ve tried a few options with conditions in the if statement. None worked. The decreasePlayerHealth function should only run when the bullet hits the player.

Web Development Query [closed]

Is learning HTML, CSS, Javascript in today AI generation is worth it or learning only useful content from this.

I want some genuine answer is is working professional?

Learning HTML, CSS, Javascript from starting to depth is very big challenge and from my point of view it is waste of time, so only useful content from html, css, js is necessary.

Optional chaining error in old browser (Chrome <80)

I started to get reports about users that can’t run the app (React) on the old browser. I did some debugging and turned out it’s all because of optional chaining used in the date-fns package.
The error in the console is:

vendor.js?id=90110bbd2ec643f1abf946793e283132:2 Uncaught SyntaxError:
Unexpected token ‘.’

And when I open vendor.js compiled file I can see the issue is about:

n?.roundingMethod

I can see that below Chrome 80 optional chaining is not supported: https://caniuse.com/mdn-javascript_operators_optional_chaining.

I tried supporting it via babel.config.js file by adding @babel/plugin-transform-optional-chaining plugin:

module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        corejs: 3.8,
        modules: false,
        targets: '> 0.5%, last 2 versions',
        useBuiltIns: 'entry',
      },
    ],
    '@babel/preset-react',
    '@babel/preset-typescript',
  ],
  plugins: [
    'styled-components',
    '@babel/plugin-transform-class-properties',
    '@babel/plugin-syntax-dynamic-import',
    '@babel/plugin-transform-optional-chaining',
  ],
  env: {
    test: {
      plugins: [
        '@babel/plugin-transform-runtime',
        '@babel/plugin-transform-modules-commonjs',
        '@babel/plugin-transform-optional-chaining',
        'dynamic-import-node',
      ],
    },
  },
};

Then I also tried adding Chrome 79 explicitly in the same file:

targets: '> 0.5%, last 2 versions, Chrome 79'

That also did not help so finally I added it to the webpack config file

use: [
  {
    loader: 'babel-loader',
    options: {
      plugins: ['@babel/plugin-transform-optional-chaining'],
      presets: ['@babel/preset-env'],
    },
  },
],

None of the above helped. Am I doing something wrong or missing something obvious? Or maybe since that’s an error from the external package I should handle it separately?

Issues with Tab Navigation: Content Tab Not Remaining Active on Navigation from the other tabs

var activeMainTab = "Previous";
var activeVerticalTab = "Content";
var activeNestedTab = {};

// Function to open main horizontal tabs
function openTab(evt, tabName) {
    var i, tabcontent, tablinks;
    tabcontent = document.getElementsByClassName("tabcontent");
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }
    tablinks = document.getElementsByClassName("tablinks");
    for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
    }
    document.getElementById(tabName).style.display = "block";
    if (evt) {
        evt.currentTarget.className += " active";
    }

    activeMainTab = tabName;

    // If switching to Previous tab, show the last active vertical tab
    if (tabName === "Previous") {
        openVerticalTab(null, activeVerticalTab);
    } else {
        // For Present and Future, open the first vertical tab
        var firstVerticalTab = document.getElementById(tabName).getElementsByClassName("tablinks-vertical")[0];
        if (firstVerticalTab) {
            firstVerticalTab.click();
        }
    }
}

// Function to open vertical tabs
function openVerticalTab(evt, tabName) {
    var i, tabcontent, tablinks;
    tabcontent = document.getElementsByClassName("vertical-tabcontent");
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }
    tablinks = document.getElementsByClassName("tablinks-vertical");
    for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
    }
    var tabContent = document.getElementById(tabName);
    if (tabContent) {
        tabContent.style.display = "block";
    }

    // If evt is null, it means we're calling this function programmatically
    if (evt) {
        evt.currentTarget.className += " active";
    } else {
        // Find the button for this tab and add the active class
        var button = Array.from(tablinks).find(btn => btn.textContent.trim() === tabName);
        if (button) {
            button.className += " active";
        }
    }

    activeVerticalTab = tabName;

    // Open the first nested tab if it exists
    var firstNestedTab = tabContent.getElementsByClassName("tablinks-nested")[0];
    if (firstNestedTab) {
        firstNestedTab.click();
    }
}

// Function to open nested horizontal tabs
function openNestedTab(evt, tabName) {
    var verticalTabContent = evt.currentTarget.closest('.vertical-tabcontent');
    var i, tabcontent, tablinks;
    tabcontent = verticalTabContent.getElementsByClassName("nested-tabcontent");
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }
    tablinks = verticalTabContent.getElementsByClassName("tablinks-nested");
    for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
    }
    document.getElementById(tabName).style.display = "block";
    evt.currentTarget.className += " active";

    activeNestedTab[activeVerticalTab] = tabName;
}

// Function to set initial active tabs on page load
function setInitialActiveTabs() {
    // Activate Previous tab
    openTab({ currentTarget: document.querySelector('.tablinks') }, "Previous");

    // Activate Content tab
    openVerticalTab(null, "Content");

    // Activate first nested tab under Content
    var firstNestedTab = document.querySelector('#Content .tablinks-nested');
    if (firstNestedTab) {
        firstNestedTab.click();
    }
}

// Call setInitialActiveTabs when the page loads
window.onload = setInitialActiveTabs;

I’m having trouble with a tab navigation system where I need to manage multiple levels of tabs. Here’s a brief overview of my requirements:

Main Tabs: Horizontal tabs for Previous, Present, and Future.
Vertical Tabs: Tabs that appear when a main tab is selected.
Nested Tabs: Tabs within the vertical tab content. However the issue is when switching between main tabs (Present, Future), the Content vertical tab does not remain active when coming back to the Previous tab.