Web scraping issue from Text Node from a website with dynamic content

I am working on a project to scrape data from the following website:

https://search.hotellook.com/hotels?=1&adults=2&checkIn=2024-03-19&checkOut=2024-03-26&children=&currency=gbp&destination=Lisbon&language=en_us&marker=google.Zz93ac967d879848dba99b874-126017#f

I am using Node JS & have used Puppeteer. I have managed to scrape everything except price of a hotel from the website. I am attaching the screenshot to point out what price I am interested in to scrape.

I have tried the following variations but they all return null or empty values. I am not sure what is going on:

const price = element.querySelector('.main_gate-price .currency_font currency_font--gbp').textContent;
const price = element.querySelector('.currency_font currency_font--gbp').textContent;
const price = element.querySelector('.card-main_gate .main_gate-price_info .currency_font.currency_font--gbp').innerText;

I have used the above variations with “textContent”, “innerHTML”, “innerText” but nothing when it clearly seems that the price is stored as a text node in the span element with class “currency_font currency_font–gbp”.

Can someone please assist & point me in right direction? The image I was referring to for reference:

Price Scrape Reference

The problem with generating a generic response for Swagger in Nest.js

The problem with generating a generic response for Swagger in Nest.js

Description

In the Nest.js application, for GET controllers (retrieving a list of items), I want to generate a sample response in Swagger. The response object contains fields: status, notification, and an object called details. Inside the details object, there are pagination information and an items field, which is an array of returned elements. The items array should be passed generically because the type of returned elements will vary for different controllers. According to the Nest.js documentation, to pass a generic type, a custom decorator needs to be created (in my case, it’s called ApiPaginatedResponse).

What’s the problem?

Unfortunately, when items are nested within the details object, they are generated outside of the details object. The documentation does not include an example with nesting (double generic passing).

What do I want to achieve?

The items array should be located inside the details object. Perhaps someone has encountered a similar issue and can help me. I’ve tried many ways already, but I don’t think I fully understand how it works.

Dto’s:

export class GetUsersDto {
  id: number;
  first_name: string;
  last_name: string;
  email_address: string;
}

export class Pagination {
  pageSize: number;
  total: number;
  current: number;
}

export class Details<TData> {
  @ApiProperty({ type: Pagination })
  pagination: Pagination;

  @ApiProperty()
  items: TData[];
}

export class PaginatedResponseDto<TData> {
  @ApiProperty()
  status: number = 200;

  @ApiProperty({ type: NotificationDto })
  notification: NotificationDto;

  @ApiProperty()
  details: Details<TData>;
}

Controller getUsers:

@Get('get-users')
  @ApiPaginatedResponse(GetUsersDto)
  async getUsers(
    @Query() filterDto: GetUsersFilterDto,
    @Req() { user: { userId } }: TUserReq,
    @Res() res: Response,
  ): Promise<Response<TResponse>> {
    const result = await this.adminInstitutionService.getUsers(filterDto, userId);
    return res.status(result.status).send(result);
  }

ApiPaginatedResponse.decorator.ts:

import { applyDecorators, Type } from '@nestjs/common';
import { ApiExtraModels, ApiOkResponse, getSchemaPath } from '@nestjs/swagger';
import { PaginatedResponseDto } from '../dto';

export const ApiPaginatedResponse = <TModel extends Type<any>>(model: TModel) => {
  return applyDecorators(
    ApiExtraModels(PaginatedResponseDto, model),
    ApiOkResponse({
      schema: {
        allOf: [
          { $ref: getSchemaPath(PaginatedResponseDto) },
          {
            properties: {
              items: {
                type: 'array',
                items: { $ref: getSchemaPath(model) },
              },
            },
          },
        ],
      },
    }),
  );
};

The generated response. As you can see, items are generated outside of the details object.

{
  "status": 200,
  "notification": {
    "title": "string",
    "message": "string"
  },
  "details": {
    "pagination": {
      "pageSize": 0,
      "total": 0,
      "current": 0
    },
    "items": [
      "string"
    ]
  },
  "items": [
    {
      "id": 0,
      "first_name": "string",
      "last_name": "string",
      "email_address": "string",
    }
  ]
}

Apex chart tooltip shared not working if series have different size

If my series have different sizes apexchart doesn’t render tooltip shared with value with same x point.
Follow codepen

var ts2 = 1484418600000;
var dates = [];
var dates2 = [];
for (var i = 0; i < 120; i++) {
  ts2 = ts2 + 86400000;
  var innerArr = [ts2, i * Math.floor(Math.random() * 220)];
  var innerArr2 = [ts2, i * Math.floor(Math.random() * 400)];
  dates.push(innerArr);
  dates2.push(innerArr2);
  
}

dates2.push([ts2 + 86400000, 1000]);
console.log(dates)

var options = {
  chart: {
    type: "line",
    stacked: false,
    height: 250,
    zoom: {
      type: "x",
      enabled: true
    },
    toolbar: {
      autoSelected: "zoom"
    }
  },
  dataLabels: {
    enabled: false
  },
  series: [
    {
      name: "XYZ MOTORS",
      data: dates
    },{
      name: "asdasd",
      data: dates2
    }
  ],
  markers: {
    size: 0
  },
  title: {
    text: "Stock Price Movement",
    align: "left"
  },
  xaxis: {
    type: "datetime"
  },

  tooltip: {
    shared: true,
  }
};

var chart = new ApexCharts(document.querySelector("#chart"), options);

chart.render();

https://codepen.io/Fernando-BA-the-animator/pen/XWQjYmX

I want the tooltip shows all series value with same x point.
And I cannot find any solution for this bug, maybe this is an issue with apex chart library.

Stripe UI for subscriptions with multiple products

Is there a React Stripe or UI Stripe out-of-the-box solution for upgrading/downgrading subscriptions with multiple products?
The Stripe portal can only handle upgrading and downgrading subscriptions with 1 product. I don’t see anything in the React Stripe or other stripe docs any other ways to go about this other than building a custom UI solution.

Tried to use the Stripe portal or Stripe checkout, but neither of them can handle upgrading subscriptions with multiple products.

Wait for javascript to render element into DOM to then see the height of the appended element

Suggested answers to posted questions don’t really show a solution to a very common issue. I haven’t seen a method of having javascript render an element into the DOM and then looping back to read the properties of the inserted element.

I’m working on a custom text scroller. My code appends divs with the words from an array like so:

wordsArray.forEach((word, index) => {
    $('#adjective').append(`<div style='opacity: ${index === 0 ? 1 : 0};'>${word}</div>`)
})

Without explicitly stating the height of the div, I’d like to read the div’s height once it’s already painted in the DOM. I’d like the forEach loop to finish, to then read one of the divs inside #adjective element. I don’t want to use setTimeout.

Any help is greatly appreciated!

Can Javascript DataTables show raw/literal strings instead of interpretting escape characters?

I’ve built a Flask app that displays text data from CSV files uploaded by the user in a DataTable. Occasionally a text might include escape characters or even a bit of code/tags. I want all text to display exactly as it was written in the original file, including any escape characters or other code/tags. For reasons I don’t need to get into, solutions involving replacing characters within the text itself will not work for my use case (so an extra backslash or ascii character or something is unacceptable).

Is there a way to achieve this?

Below is some javascript code I had hoped would work using String.raw, but it still renders “This is <b>bold</b>” as “This is bold“. Not what I expected.

simplified code:

\ the data['table'] JSON object was created in Python with pd.DataFrame.to_dict(orient='records')


function prepareTables(data) {
    
    // build table to show input data
    var data_table = $(`#data-table`).DataTable();
    data_table.clear();

    data['table'].forEach(function(item) {
        //insert rows
        data_table.row.add([
            item.id, String.raw`${item.text}`, item.some_number
        ])
    })
    data_table.draw();

How to stop the execution of a listener when a new event occurs?

I am writing a small web app and I dont want to use a js framework. That’s why I am encouring some issues now.

The following snippet is responsible for the navigation. When a popstate event occurs, it show the spinner, initiates the page and shows it.

import spinner from "./pages/spinner/spinner.js";
import dashboard from "./pages/dashboard/dashboard.js";
import grid from "./pages/grid/grid.js";

const pages = {
    dashboard,
    grid,
};

window.addEventListener("popstate", async () => {
    const body = document.getElementsByTagName("body")[0];

    body.replaceChild(await createMain(spinner), document.getElementsByTagName("main")[0]);

    const route = window.location.hash.replace(/#/g, "");
    const page = pages[route];

    const initiatedPage = await page.init(await createMain(page));
    body.replaceChild(initiatedPage, document.getElementsByTagName("main")[0]);
});

history.pushState(null, null, "#dashboard");
window.dispatchEvent(new PopStateEvent("popstate", null));

async function createMain(page) {
    const template = await fetch(page.templateUrl);

    const main = document.createElement("main");
    main.classList.add(...page.classes);
    main.innerHTML = await template.text();

    return main;
}

Problem:

  • If a user now clicks a link twice the code inside the listener runs in parallel and have some side effect.

I need to find a solution where the second clicks stops the execution of the first one.

Do you have any ideas?

Trying to create a responsive nav bar for smaller device, but after clicking the button everything disappears

I am trying to create a sample responsive web page with navigation bar for big as well as small screens. I have done with the part for big screens. I am trying to create for smaller screen devices, with a navigation button which after clicking should open the navigation bar from top.

I have tried creating a function and link it to the navbar button, but after clicking that button everything on the page just keeps disappearing and page gets blank. Please help me out with this.

What I want is, when user clicks on the ≡ navbar button, navbar should open and at the same time close ❌ button should appear for closing, in the place navbar button ≡ and again replaced by same after closing.

Here is my code, need help!

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
  <style type="text/css" media="all">
    * {
      margin: 0;
      padding: 0;
    }
    
    a {
      text-decoration: none;
    }
    
    .navbar-small {
      display: none;
    }
    
    #navbar {
      width: 100%;
      background: #f44336;
      display: inline-block;
    }
    
    #navbar>a {
      color: #ffffff;
      margin: 0;
      padding: 12px 20px;
      float: left;
    }
    
    #navbar>a:hover {
      background: #ffffff;
      color: #f44336;
      cursor: pointer;
    }
    
    @media only screen and (max-width: 770px) {
      #navbar {
        display: none;
      }
      .navbar-small {
        width: 100%;
        background: #f44336;
        display: flex;
        flex-direction: column;
      }
      .navbar-small>.nav-menu {
        display: inline-block;
        width: 100%;
      }
      .navbar-small>.nav-menu>a {
        color: #ffffff;
        margin: 0;
        padding: 12px 20px;
      }
      .navbar-small>.nav-menu>a:hover {
        background: #ffffff;
        color: #f44336;
        cursor: pointer;
      }
      .navbar-small>.hidden {
        display: none;
        width: 100%;
        text-align: center;
        margin: 0;
        color: #ffffff;
      }
      .navbar-small>.hidden>a {
        width: 100%;
        float: none;
        display: block;
        padding: 12px 0;
        color: #ffffff;
      }
      .navbar-small>.hidden>a:hover {
        background: #ffffff;
        color: #f44336;
        cursor: pointer;
      }
    }
  </style>
</head>

<body>
  <div class="navbar-small">
    <section class="nav-menu">
      <a href="#" style="float: left;">Home</a>
      <a class="nav-btn" href="#" style="float: right;" onclick="open()"><i class="fa fa-bars"></i></a>
    </section>
    <section class="hidden">
      <a class="link" href="#">Link 1</a>
      <a class="link" href="#">Link 2</a>
      <a class="link" href="#">Link 3</a>
      <a class="link" href="#">Link 4</a>
    </section>
  </div>
  <nav id="navbar">
    <a href="#">Home</a>
    <a href="#">Link 1</a>
    <a href="#">Link 2</a>
    <a href="#">Link 3</a>
    <a href="#">Link 4</a>
  </nav>
  <header id="header">
  </header>

  <script type="text/javascript" charset="utf-8">
    function open() {
      document.getElementsByClassName("hidden").style.display = "block";
    }
  </script>
</body>

</html>

changing mouse cursor with javascript

const observer = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
        console.log(entry)
        if (entry.isIntersecting) {
            entry.target.classList.add('show');            
        } else {
            entry.target.classList.remove('show');
        }

    });
});

const hiddenElements = document.querySelectorAll('.hidden');
hiddenElements.forEach((el) => observer.observe(el));

const trailer = document.getElementById("trailer");

window.onmousemove = e => {
    const x = e.clientX - trailer.offsetWidth / 2;
    const y = e.clientY - trailer.offsetHeight / 2;
    const interactable = e.target.closest(".interactable");
    const interacting = interactable !== null;

    trailer.style.transform = `translate(${x}px, ${y}px)`;

    changeScale(interacting);
}

const changeScale = (interacting) => {

    const keyframes = {
        transform: `scale(${interacting ? 2 : 1})`
    }

    trailer.animate(keyframes, {
        duration: 800,
        fill: "forwards"
    });
}
/* Main */
body {
    margin: 0;
    font-family: "Roboto", sans-serif;
    color: white;
    background: rgb(20, 20, 20);
    cursor: none;
}
  
section {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    align-content: center;
    min-height: 100vh;
    padding: 100px 20vw;
    font-size: 20px;
}

#trailer {
    height: 20px;
    width: 20px;
    background-color: white;
    border-radius: 20px;

    position: fixed;
    left: 0px;
    top: 0px;
    z-index: 10000;

    pointer-events: none;
    opacity: 0;
    transition: opacity 500ms ease;
}

.interactable {
    
}

body:hover > #trailer {
    opacity: 1;
}

/* Social Media Icons */
 .wrapper {
    display: inline-flex;
}
.wrapper .icon{
    margin: 0 20px;
    text-align: center;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    position: relative;
    z-index: 2;
    transition: 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
.wrapper .icon span {
    display: block;
    height: 60px;
    width: 60px;
    background: #000;
    border-radius: 50%;
    position: relative;
    z-index: 2;
    box-shadow: 0px 10px 10px rgba(0,0,0,0.1);
    transition: 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
.wrapper .icon span i{
    line-height: 60px;
    font-size: 25px;
}
.wrapper .icon .tooltip{
    position: absolute;
    top: 0;
    z-index: 1;
    background: #fff;
    color: #FFF;
    padding: 10px 18px;
    font-size: 20px;
    font-weight: 500;
    border-radius: 25px;
    opacity: 0;
    pointer-events: none;
    box-shadow: 0px 10px 10px rgba(0,0,0,0.1);
    transition: 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
.wrapper .icon:hover .tooltip{
    top: -70px;
    opacity: 1;
    pointer-events: auto;
}
.icon .tooltip:before{
    position: absolute;
    content: "";
    height: 15px;
    width: 15px;
    background: #fff;
    left: 50%;
    bottom: -6px;
    transform: translateX(-50%) rotate(45deg);
    transition: 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
.wrapper .icon:hover span{
    color: #fff;
}
.wrapper .icon:hover span,
.wrapper .icon:hover .tooltip{
    text-shadow: 0px -1px 0px rgba(0,0,0,0.4);
}

.wrapper .discord:hover span,
.wrapper .discord:hover .tooltip,
.wrapper .discord:hover .tooltip:before{
    background: #7289da;
}
.wrapper .github:hover span,
.wrapper .github:hover .tooltip,
.wrapper .github:hover .tooltip:before{
    background: #333;
}
.wrapper .youtube:hover span,
.wrapper .youtube:hover .tooltip,
.wrapper .youtube:hover .tooltip:before{
    background: #DE463B;
}

/* Animation Class */
.hidden {
    opacity: 0;
    filter: blur(5px);
    transform: translateY(10%);
    transition: all 1s;
}

.show {
    opacity: 1;
    filter: blur(0);
    transform: translateY(0);
}

.changing-text {
    animation-name: fontChange;
    animation-duration: 5s;
    animation-iteration-count: infinite;
}


/* Fonts */
.playfair-display-font {
    font-family: "Playfair Display", serif;
    font-optical-sizing: auto;
    font-weight: 400;
    font-style: normal;
  }
.roboto-regular {
    font-family: "Roboto", sans-serif;
    font-weight: 400;
    font-style: normal;
  }

  .madimi-one-regular {
    font-family: "Madimi One", sans-serif;
    font-weight: 400;
    font-style: normal;
  }


/* Animations etc. */
@keyframes fontChange {
    0% {
        font-family: 'Times New Roman';
    }
    10% {
        font-family: 'Courier New';
    }
    20% {
        font-family: 'Madimi One';
    }
    30% {
        font-family: 'Tahoma';
    }
    40% {
        font-family: 'Arial';
    }
    50% {
        font-family: 'Georgia';
    }
    60% {
        font-family: 'Comic Sans MS';
    }
    70% {
        font-family: 'Trebuchet MS';
    }
    80% {
        font-family: 'Playfair Display';
    }
    90% {
        font-family: 'Brush Script MT';
    }
    100% {
        font-family: 'Roboto';
    }
}

@media(prefers-reduced-motion) {
    .hidden {
        transition: none;
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Madimi+One&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"/>
    <link href="https://fonts.googleapis.com/css2?family=Madimi+One&family=Playfair+Display:ital,wght@0,400..900;1,400..900&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="style.css">
    <script defer src="app.js"></script>

</head>
<body>

    <div id="trailer">

    </div>

    <section class="hidden">
        <h1 class="changing-text" style="font-size: 120px;">My Website</h1>
        <p>Look at these Animations!</p>
    </section>
    <section class="hidden">
        <h2 style="padding-bottom: 20px;">Coder &#60;/&#62;</h2>
        <img src="https://i.ibb.co/0GQCkNK/ubuntu-term.png" alt="vim" height="650" style="box-shadow: 10px 10px 5px rgb(5, 5, 5);">
    </section>
    <section class="hidden">
        <h2>New</h2>
        <p>Amet dignissimos laudantium similique pariatur provident quod repellat id laborum recusandae modi. Ullam nulla fugit officia. Ratione minus, quos natus repudiandae ducimus aspernatur harum, possimus odio magni hic tempore incidunt!</p>
    </section>
    <section class="hidden">
        <h2>New</h2>
        <p>Delectus ratione animi doloribus sunt eius, unde reiciendis provident illum deleniti consequuntur quidem necessitatibus expedita quod enim voluptas corrupti quas repellat rem autem, pariatur maiores asperiores sint voluptatibus! Illum, voluptates.</p>
    </section>
    <section class="hidden">
        <h2 style="padding-bottom: 20px;">Find me on:</h2>
        <div class="wrapper">
            <a href="https://discord.gg/KQjcgkZ3aJ" target="_blank" style="text-decoration: none; color: inherit;"><div class="icon discord interactable">
               <div class="tooltip">
                  Discord
               </div>
               <span><i class="fab fa-discord"></i></span>
            </div></a>
            <a href="https://github.com/illy-dev" target="_blank" style="text-decoration: none; color: inherit;"><div class="icon github interactable">
               <div class="tooltip">
                  Github
               </div>
               <span><i class="fab fa-github"></i></span>
            </div></a>
            <a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ" target="_blank" style="text-decoration: none; color: inherit;"> <div class="icon youtube interactable">
               <div class="tooltip">
                  YouTube
               </div>
               <span><i class="fab fa-youtube"></i></span>
            </div></a>
         </div>
    </section>
</body>
</html>

In the script my Custom cursor is in the top left corner what means that something is wrong. I’m new to Javascript so can anyone help me what I did wrong. Ignore that the Image doesn’t work just look at the cursor and the interactables at the bottom. I tried to made that the cursor animates getting bigger if I hover over the interactable.

Select2 – Set val IF selected option == “Apple”

I have a select2 drop down and would like to know the best way to SET a VALUE if the OPTION selected == ” Apple” for instance.

Here is my Select2

<select id="fruit" title="fruit" name="fruit"
                                      class="form-control select2-single">
                                  <option value="">&nbsp;</option>
                                  <option value="">Apple</option>
                                  <option value="">Lemon</option>
                              </select>

What I’d like to achieve is:

If Option “Apple” is selected, SET Value to THISVARIABLE (I get responses from an AJAX Post and would like to dynamically set the Value

“server: [object Object]” this is getting printed on the receivers screen

Building a chatApp using ws library.
Server.js

const http = require('http');
const WebSocket = require('ws'); // Import the 'ws' library

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('WebSocket servern');
});

const wss = new WebSocket.Server({ server });

// Array to store connected clients
const clients = [];

wss.on('connection', ws => {
  console.log('Client connected');

  // Add client to the list
  clients.push(ws);

  ws.on('message', message => {
    console.log(`Received: ${message}`);

    // Broadcast message to all clients except the sender
    wss.clients.forEach(client => {
        if (client !== ws && client.readyState === WebSocket.OPEN) {
          const dataToSend = JSON.stringify({ message, sender: 'server' });
          client.send(dataToSend);
        }
      });
  });

  ws.on('close', () => {
    console.log('Client disconnected');
    removeClient(ws);
  });

  function removeClient(ws) {
    const index = clients.indexOf(ws);
    if (index !== -1) {
      clients.splice(index, 1);
    }
  }
});

const PORT = 3000;
server.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

client.js

// client.js
let ws;

document.addEventListener('DOMContentLoaded', () => {
  ws = new WebSocket('ws://localhost:3000');
  const chatWindow = document.getElementById('chat-window');

  // Event handler for incoming messages
  ws.onmessage = event => {
    const messageData = JSON.parse(event.data);
    console.log('Received message data:', messageData); // Debugging log
    const { message, sender } = messageData;

    if (sender !== 'self') {
      console.log('Appending message:', message); // Debugging log
      appendMessage(messageData); // No need to pass chatWindow here
    }
  };
});

// Function to send a message
function sendMessage() {
  const messageInput = document.getElementById('message-input');
  const message = messageInput.value.trim();
  if (message !== '') {
    ws.send(JSON.stringify({ message }));
    messageInput.value = '';
  }
}

// Function to append a message to the chat window
function appendMessage(messageData) {
  const chatWindow = document.getElementById('chat-window'); // Access chatWindow directly
  const { message, sender } = messageData;

  console.log('Appending actual message:', message);
  const messageElement = document.createElement('div');
  messageElement.textContent = `${sender}: ${message}`; // Display sender's name with the message
  messageElement.classList.add('message-bubble');
  chatWindow.appendChild(messageElement);
  chatWindow.scrollTop = chatWindow.scrollHeight;
}

document.addEventListener('DOMContentLoaded', () => {
  const sendButton = document.getElementById('send-btn');
  sendButton.addEventListener('click', sendMessage);
});

On sending message to other sockets it is printing server: [object Object] I am not able to get that also I logged the messages on the console enter image description here

So this is the screenshot of the console. Not able to get what might be the issue. Is it in type conversion or some other element is causing issue.
For more info below is the index.html code to give a better view
Index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Real-Time Chat</title>
  <link rel="stylesheet" href="styles.css">
  <script src="./client.js"></script>
</head>
<body>
  <div class="container">
    <div id="chat-window" class="chat-box"></div>
    <div class="input-container">
      <input type="text" id="message-input" placeholder="Type your message...">

      <button id="send-btn" onclick="sendMessage()">Send</button>
    </div>
  </div>
 
</body>
</html>

How to create a table of contents from Strapi rich text field

I’ve searched everywhere for this but I could only find one article about it which was pretty vague.

So I’m rendering the rich text content using the BlocksRenderer component from Strapi itself. Is it possible to create a table of contents from the data gotten from strapi rich text?

This is my Blog component:

import { BlocksRenderer, type BlocksContent} from "@strapi/blocks-react-renderer";

const Blog = () => {

  const { data } = useGetBlogsByIdQuery(slug);

  const content: BlocksContent = data ? .data ? .attributes ? .content;

  return ( 
    <BlocksRenderer content = {content} />
  )
}

This is how the blog post is rendered. If I can map out the headings of each section of the content below the 'on this page' text

This is what the content data looks like

I would appreciate any tips

Why matrix.shift() is almost 25x faster than indexing in this javascript code

I noticed this behaviour while solving this leetcode problem:
https://leetcode.com/problems/search-a-2d-matrix/description/

Here is the code:

function searchMatrix(matrix, target) {
    const len = matrix.length;

    for (let i = 0; i < len; i++) {
        //const row = matrix.shift();  // if i access row using matrix.shift() the code executes in less than 100 ms. 
        const row = matrix[i]   // But if i access the row via indexing.  then it takes more than 2000ms and sometimes even gives Time limit exceeded.
        let start = 0, end = row.length - 1;

        while (start <= end) {
            const mid = start + Math.floor((end - start) / 2);

            if (row[mid] === target) return true;

            if (row[mid] < target) {
                start = mid + 1;
            } else {
                end = mid - 1;
            }
        }
    }

    return false;
}

In this code if i access row using const row = matrix.shift(); the code executes in less than 100 ms.
but if i access the row via indexing using const row = matrix[i] . then it takes more than 2000ms and sometimes even gives Time limit exceeded.

Please help me understand why there is such a huge performance difference.

I checked Ecma script specifications here:
https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.shift
and for shift() , internally java script also uses a while loop with indexing so it should take O(n) time for each row and it should be slower than indexing.

i Tried ChatGpt and Gemini and got some info. But it dint cite any reference so it might be making things up or hallucinating. here is the answer Gemini gave:

“Here are key factors contributing to shift()’s efficiency:

Built-in Optimizations: JavaScript engines are heavily optimized for common array operations like shift(). They often implement them using low-level code that’s significantly faster than plain JavaScript loops. These optimizations can include:

In-Place Shifting: Manipulating internal pointers to elements within the same memory block, minimizing data movement and avoiding unnecessary memory reallocations.
Cache-Friendly Rearrangement: Reordering elements in a way that maximizes cache utilization, leading to faster access times for subsequent operations.
Hidden Overheads in for Loops: While for loops appear simpler, they can involve subtle overheads that shift() often avoids:

Variable Lookups: Each iteration of a for loop requires looking up loop variables and condition values, adding some overhead.
Bounds Checks: Loops often involve explicit bounds checks to ensure array access is within valid limits, potentially incurring additional costs.
Potentially Less Efficient Rearrangement: Manually rearranging elements in a for loop might not always be as cache-friendly as the optimized implementations used for shift().
Additional Considerations:

Array Size: The performance difference between shift() and indexing can become more pronounced with larger arrays, as shift()’s optimizations become more beneficial for larger data sets.
Data Types: The specific data types stored in the array can also influence performance, as optimizations might be tailored for certain types (e.g., numbers).”

how can i share a list from one js to another?

thanks for everyone who heloed me today already. i was told to use a storage to share the info and… well it didnt work.

I need to share the list that user made from list.js to dragANDdrop.js. from dragANDdrop.js i want to show this on html. well the list is not showing, i can’t get why so

here is what i tried
list.js

localStorage.setItem('lst', list);

dragANDdrop.js

list = localStorage.getItem('lst');
const html = list.map((item) => `<li>${item}</li>`).join('');
document.querySelector('ul').innerHTML = html;

the second part should display the list on the html page.

dragANDdrop.html

<section class="home-section">
    <div class="home-content">
        <i class='bx bx-menu' ></i>
        <span class="text"><h1>To do list</h1></span>
        <ul></ul>  
    </div>
</section>
<script src="list.js"></script>
<script src="dragANDdrop.js"></script>