How to map visible text indices to their location in an HTML tree

I am trying to implement a web-based rich text editor that will automatically decorate the user’s text while he’s typing (think spellcheck).

The issue is that the server only processes raw text, and returns annotations with their index + length in the raw text.

So the complete flow must look like :

  1. When spellcheck routine triggers, it converts the contents of the HTML structure into raw text.
  2. Query the server for spellcheck annotations.
  3. From the returned indices, find out the corresponding HTML portion and surround it with underline tags.

So I first tried Rangy and especially the TextRange module. But I am getting inconsistent results, the generated string for step 1 is hard to predict, and sometimes incorrect (see example below).

<!-- Rangy's TextRange.text() yields "foo bar" while the user sees "foobar" -->
<span>foo</span>
bar

I’m looking for a solution that would be quite robust, that can handle unicode characters, words that are cut in middle by a tag, or any other weird HTML structure.

FYI I am using Pell rich editor but the problem is the same with any contenteditable-based editor, and if another one solves this poblem I will happily switch.

What’s the best way to achieve this goal?

How to open a new tab in spa with vanilla JavaScript?

I am trying to make a SPA with html, css and vanilla JS (I have very little idea of JS). The problem I have is that the method I’m using, works correctly, but when I open one of the sections in a new tab, it does not address the web correctly and gives an error “Cannot GET”.
Is there any way to solve this, in a simple way, only with vanilla js?

const route = (event) => {
  event = event || window.event;
  event.preventDefault();
  window.history.pushState({}, "", event.target.href);
  handleLocation();
};

const routes = {
  404: "./pages/404.html",
  "/": "./pages/index.html",
  "/vehicles": "./pages/vehicles.html",
  "/services": "./pages/services.html",
  "/contact": "./pages/contact.html",
  "/financing": "./pages/financing.html",
  "/locations": "./pages/locations.html",
};

const handleLocation = async () => {
  const path = window.location.pathname;
  const route = routes[path] || routes[404];
  const html = await fetch(route).then((data) => data.text());
  document.getElementById("main-page").innerHTML = html;
};

window.onpopstate = handleLocation;
window.route = route;

handleLocation();

get geometry of items using web-ifc-viewer

hello im experimenting with web-ifc-viewer, and im currently to to get the geometry of a certain object by its express id or by pointing and clicking on it.

i have searched thoroughly in ifcviwer.context.item couldn’t find anything.-

also if have to use web-ifc-viewer, how do i implement it with web-ifc-viewer in a react application.

I have went through every web-ifc-viewer method but could not find any that would give me the geometry of the target by its id or clicking on it, although there are many methods to use after you can get your hands on the objects mesh or geometry, that’s what I need it for.

The best way to securing react JS Route based on roles

So I already implemented private routing in react JS with the help library from react-aad-msal. When the user does not authorize It will show a landing page to ask the user to log in. The next step is we want to limit what the user can and cannot see. We Have Table Users that contain the Email and what Role the user belongs to, we also have another table securityrolesdetail this table will return all the route the User Roles has. So we create an API this API will return All the Routes the User has in the React App, and the returned data from API will filter the main ListRouter Array in the React App. I already implemented all that but I just want to be certain that this is the best practice and doesn’t have a flaw.
My Code is looking like this.

export const ListRouter = [
{
    id: "1",
    title: "Menu1",
    linkto: "/Menu1",
    paths: '/Menu1',
    elements: <Menu1/>
},
{
    id: "2",
    title: "Menu2",
    linkto: "/Menu2",
    paths: '/Menu2',
    elements: <Menu2/>
}, 
{
    id: "3",
    title: "Menu3",
    linkto: "/Menu3",
    paths: '/Menu3',
    elements: <Menu3/>
}
]

And then in the App.Js we called an API to return all the available router.

API Rerturn
["/menu1", "/menu2"]

After we got the data from the API then we filter the ListRouter based on the returned data in useeffect

 const routerResult = await getFormListRouter().then(x => {
                var userModule = x.data;
                var module = ListRouter.filter((x) => {
                    if (userModule.indexOf(x.linkto.toString().toLowerCase()) > -1) {
                        return x;
                    }
                });
                setRouters(module);
            });

After that we use the state in the component to render all the Router so when user don’t have the permission to the page it will return no router match

                    <Routes>
                        {routers.map((listmap) => (
                            <Route
                                path={listmap.paths}
                                element={listmap.elements}
                                key={listmap.id}
                            />
                        ))}
                    </Routes>

For now this Already work, the user can’t open the menu3 in the browser. From this Implementation is there anything should I concern, or I can add to make it more secure.

Endless event propagation with onmouseover and onmouseout event?

I’m working on making a checkbox appear when a user hovers over a table’s first data cell.
I used “firstDataCell.onmouseover” to add the checkbox and “firstDataCell.onmouseout” to remove it which works as the checkbox appears but you are unable to click on the checkbox as the events propagate when you’ve hovered on it. I think the solution would be in some way to stop the other event propagation while one event is active but can’t seem to work it out with “.stopPropagation()”.
Code bellow:

let taskTable=document.querySelector('#table_1')
let tableBody=taskTable.getElementsByTagName('tbody')[0].getElementsByTagName('tr')
let tableRowArr=[]
for(let i=0;i<tableBody.length;i++){
    tableRowArr.push(tableBody[i])
}
tableRowArr.forEach((row,index) => {
    let tableRowFirstDataCell=row.getElementsByTagName("td")[0]
    let cellData=tableRowFirstDataCell.innerHTML
    tableCellsData.push(cellData)
    tableRowFirstDataCell.onmouseover=addCheckboxes
})

function addCheckboxes(event){
        event.currentTarget.onmouseover=()=>{}
        event.currentTarget.innerHTML=""
        let checkBox=document.createElement("input")
        checkBox.setAttribute("type","checkbox")
        checkBox.setAttribute("class","check")
        // checkBox.setAttribute("") //<-----  Add styling to checkboxes
        // checkBox.addEventListener("onclick",deleteTask(id))
        event.currentTarget.appendChild(checkBox)
        event.currentTarget.onmouseout=removeCheckboxes
}
function removeCheckboxes(event) {
        event.currentTarget.onmouseout=()=>{}
        event.currentTarget.innerHTML=""
        event.currentTarget.innerHTML=tableCellsData[1]
        event.currentTarget.onmouseover=addCheckboxes
}

Form Submission without Jquery [closed]

Form Submission without Jquery*
For a login to take place, the client (browser) has to POST to the server and then receive a response.
*Html SIDE

<from id="login">
<input type="email" placeholder="Enter your Email" required>
<input type="password" placeholder="Enter your Password" required>
<input type="submit" value="Login">
</form>

Javascript SIDE

const form = document.querySelector("#login");
const request =  new XMLHttpRequest();
//form submitting 
form.addEventListener("submit", function(event){
    event.preventDefault();
    request.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
           // Typical action to be performed when the document is ready:
           let  resp = JSON.parse(request.responseText);
           console.log(resp);
        }
    };
     
    request.open("POST", domain+"/api/user/register", true);
    request.send(new FormData(form));
});

Php SIDE

<?php

  $username = $_POST['username'];
  $password = $_POST['password'];

  if($username == "neoistone" )
  {
     if($password == "1234567890")
     {
        $response = json_encode([ 'status' => 'success', 'message' => 'Login success' ]);
     } else {
        $response = json_encode([ 'status' => 'error', 'message' => 'password incorrect' ]);
     }
  } else {
    $response = json_encode([ 'status' => 'error', 'message' => 'username incorrect' ]);
  }
  echo json_encode($response);
?>

This example login javascript using backend php
Happy Code Developers

How To Use A Web Browser To Take photo And Send to MySql database with validations

The HTML code is a registration form with input fields for registration number and password and a video element to capture the user’s photo. The JavaScript code uses the getUserMedia API to access the user’s camera and display the video stream in the video element. When the upload button is clicked, the video frame is drawn to a canvas, the image data is retrieved from the canvas and added to a FormData object along with the registration number and password. The registration button has a retake and upload file button displaying when the regno of the user is found in the mysql database, using php pdo. The FormData object is then sent to the server via an XMLHttpRequest to the “upload_image.php” file for processing.
The first PHP file “upload_image.php” connects to a MySQL database using PDO, retrieves the image data and registration number from the POST request, checks if the registration number exists in the database, if it does, it updates the image data in the table, if the registration number does not exist in the database, it returns an error message.
The second PHP file “verify_user.php” is called via a fetch call to verify the user by checking registration number and password, if the user is verified, it will show the video container and allow user to take a photo.
Here is my scripts:
front-end page:members.php

<html>
  <head>
    <title>Registration Form</title>
  </head>
  <body>
 <form id="registration-form" enctype="multipart/form-data">
   <div>
    <label for="regno">Registration Number:</label>
    <input type="text" id="regno">
  </div>
  <div>
    <label for="password">Password:</label>
    <input type="password" id="password">
  </div>
  <div>
    <video id="video" width="400" height="300"></video>
  </div>
  <div>
    <button type="button" id="verify">Verify</button>
    <button type="button" id="upload">Upload Image</button>
    <button type="button" id="retake">Retake</button>
    <button type="button" id="uploadFile">Upload File</button>
  </div>
</form>
<script>
// Get user media and display video stream
let video = document.querySelector('video');
navigator.mediaDevices.getUserMedia({ video: true })
  .then(stream => {
    video.srcObject = stream;
    video.play();
  });

// Capture image from video stream
let uploadButton = document.querySelector('#upload');
uploadButton.addEventListener('click', e => {
    let canvas = document.createElement('canvas');
    let context = canvas.getContext('2d');
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    context.drawImage(video, 0, 0, canvas.width, canvas.height);
    let imageData = canvas.toDataURL('image/jpeg');

    // Encrypt the parameters
    let encryptedParams = CryptoJS.AES.encrypt(JSON.stringify({
        imageData: imageData,
        regno: document.querySelector('#regno').value,
        password: document.querySelector('#password').value
    }), 'secret key');

    // Send encrypted parameters to server
    let xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = () => {
      if (xhttp.readyState == 4 && xhttp.status == 200) {
        let response = JSON.parse(xhttp.response);
        if (response.status == 'success') {
          document.querySelector('#retake').style.display = 'none';
          document.querySelector('#uploadFile').style.display = 'none';
        } else {
          alert('Error: ' + response.message);
        }
      }
    };
    xhttp.open("POST", "upload_image.php", true);
    xhttp.send(encryptedParams);
});

// Verify user
let verifyButton = document.querySelector('#verify');
verifyButton.addEventListener('click', e => {
    let regno = document.querySelector('#regno').value;
    let password = document.querySelector('#password').value;

    // Encrypt the parameters
    let encryptedParams = CryptoJS.AES.encrypt(JSON.stringify({
        regno: regno,
        password: password
    }), 'secret key');

    // Send encrypted parameters to server
    let xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = () => {
      if (xhttp.readyState == 4 && xhttp.status == 200) {
        let response = JSON.parse(xhttp.response);
        if (response.status == 'success') {
          document.querySelector('#videoContainer').style.display = 'block';
        } else {
          alert('Error: ' + response.message);
        }
      }
    };
    xhttp.open("POST", "verify_user.php", true);
    xhttp.send(encryptedParams);
});
</script>

</body>
</html>
upload_image.php script:
<?php
// upload_image.php

// Connect to MySQL database
$host = 'localhost';
$dbname = 'school';
$username = 'root';
$password = '';

try {
    $conn = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Retrieve image data from POST request
    $imageData = $_POST['imageData'];
    $regno = $_POST['regno'];

    // Check if registration number exists in database
    $stmt = $conn->prepare('SELECT * FROM users WHERE regno = :regno');
    $stmt->execute(['regno' => $regno]);
    $result = $stmt->fetch();

    // If registration number exists, update image data
    if ($result) {
        $stmt = $conn->prepare('UPDATE users SET image = :imageData WHERE regno = :regno');
        $stmt->execute(['imageData' => $imageData, 'regno' => $regno]);

        // Return success response
        echo json_encode(['status' => 'success']);
    } else {
        // Return error response
        echo json_encode(['status' => 'error', 'message' => 'Registration number does not exist in database']);
    }

} catch(PDOException $e) {
    echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
}

?>
verify_user.php:
<?php
// verify_user.php

// Connect to MySQL database
$host = 'localhost';
$dbname = 'school';
$username = 'root';
$password = '';

try {
    $conn = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Retrieve registration number and password from GET request
    $regno = $_GET['regno'];
    $password = $_GET['password'];

    // Check if registration number and password match in database
    $stmt = $conn->prepare('SELECT image FROM users WHERE regno = :regno');
$stmt->execute(['regno' => $regno]);
$imageData = $stmt->fetchColumn();

// Convert image data to varchar
$imageString = base64_encode($imageData);

// Update image data in database
$stmt = $conn->prepare('UPDATE users SET image = :imageString WHERE regno = :regno');
$stmt->execute(['imageString' => $imageString, 'regno' => $regno]);


// Check if update was successful
if ($stmt->rowCount() > 0) {
    echo 'Image data successfully updated to varchar in database.';
} else {
    echo 'Error: Image data could not be updated to varchar in database.';
}
// Close database connection
$conn = null;
} catch(PDOException $e) {
    echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
}
?>

The script isnt working..No image uploaded to database?
i want the image stored in mysql database to be in varchar and not in blob form? How do i achieve this task?

React – generating a unique random key causes infinite loop

I have a componenet that wraps its children and slides them in and out based on the stage prop, which represents the active child’s index.

As this uses a .map() to wrap each child in a div for styling, I need to give each child a key prop. I want to assign a random key as the children could be anything.

I thought I could just do this

key={`pageSlide-${uuid()}`}

but it causes an infinite loop/React to freeze and I can’t figure out why

I have tried

  • Mapping the children before render and adding a uuid key there, calling it via key={child.uuid}
  • Creating an array of uuids and assigning them via key={uuids[i]}
  • Using a custom hook to store the children in a state and assign a uuid prop there

All result in the same issue

Currently I’m just using the child’s index as a key key={pageSlide-${i}} which works but is not best practice and I want to learn why this is happening.

I can also assign the key directly to the child in the parent component and then use child.key but this kinda defeats the point of generating the key

(uuid is a function from react-uuid, but the same issue happens with any function including Math.random())

Here is the full component:

import {
    Children,
    useCallback,
    useEffect,
    useMemo,
    useRef,
    useState,
} from "react";
import PropTypes from "prop-types";
import uuid from "react-uuid";
import ProgressBarWithTicks from "./ProgressBarWithTicks";
import { childrenPropType } from "../../../propTypes/childrenPropTypes";

const calculateTranslateX = (i = 0, stage = 0) => {
    let translateX = stage === i ? 0 : 100;
    if (i < stage) {
        translateX = -100;
    }
    return translateX;
};

const ComponentSlider = ({ stage, children, stageCounter }) => {
    const childComponents = Children.toArray(children);
    const containerRef = useRef(null);
    const [lastResize, setLastResize] = useState(null);
    const [currentMaxHeight, setCurrentMaxHeight] = useState(
        containerRef.current?.childNodes?.[stage]?.clientHeight
    );

    const updateMaxHeight = useCallback(
        (scrollToTop = true) => {
            if (scrollToTop) {
                window.scrollTo(0, 0);
            }
            setCurrentMaxHeight(
                Math.max(
                    containerRef.current?.childNodes?.[stage]?.clientHeight,
                    window.innerHeight -
                        (containerRef?.current?.offsetTop || 0) -
                        48
                )
            );
        },
        [stage]
    );

    useEffect(updateMaxHeight, [stage, updateMaxHeight]);
    useEffect(() => updateMaxHeight(false), [lastResize, updateMaxHeight]);

    const resizeListener = useMemo(
        () => new MutationObserver(() => setLastResize(Date.now())),
        []
    );

    useEffect(() => {
        if (containerRef.current) {
            resizeListener.observe(containerRef.current, {
                childList: true,
                subtree: true,
            });
        }
    }, [resizeListener]);

    return (
        <div className="w-100">
            {stageCounter && (
                <ProgressBarWithTicks
                    currentStage={stage}
                    stages={childComponents.length}
                />
            )}
            <div
                className="position-relative divSlider align-items-start"
                ref={containerRef}
                style={{
                    maxHeight: currentMaxHeight || null,
                }}>
                {Children.map(childComponents, (child, i) => (
                    <div
                        key={`pageSlide-${uuid()}`}
                        className={`w-100 ${
                            stage === i ? "opacity-100" : "opacity-0"
                        } justify-content-center d-flex`}
                        style={{
                            zIndex: childComponents.length - i,
                            transform: `translateX(${calculateTranslateX(
                                i,
                                stage
                            )}%)`,
                            pointerEvents: stage === i ? null : "none",
                            cursor: stage === i ? null : "none",
                        }}>
                        {child}
                    </div>
                ))}
            </div>
        </div>
    );
};

ComponentSlider.propTypes = {
    children: childrenPropType.isRequired,
    stage: PropTypes.number,
    stageCounter: PropTypes.bool,
};

ComponentSlider.defaultProps = {
    stage: 0,
    stageCounter: false,
};

export default ComponentSlider;

It is only called in this component (twice, happens in both instances)

import { useEffect, useReducer, useState } from "react";
import { useParams } from "react-router-dom";

import {
    FaCalendarCheck,
    FaCalendarPlus,
    FaHandHoldingHeart,
} from "react-icons/fa";
import { IoIosCart } from "react-icons/io";
import { mockMatches } from "../../../templates/mockData";
import { initialSwapFormState } from "../../../templates/initalStates";
import swapReducer from "../../../reducers/swapReducer";
import useFetch from "../../../hooks/useFetch";
import useValidateFields from "../../../hooks/useValidateFields";
import IconWrap from "../../common/IconWrap";
import ComponentSlider from "../../common/transitions/ComponentSlider";
import ConfirmNewSwap from "./ConfirmSwap";
import SwapFormWrapper from "./SwapFormWrapper";
import MatchSwap from "../Matches/MatchSwap";
import SwapOffers from "./SwapOffers";
import CreateNewSwap from "./CreateNewSwap";
import smallNumberToWord from "../../../functions/utils/numberToWord";
import ComponentFader from "../../common/transitions/ComponentFader";

const formStageHeaders = [
    "What shift do you want to swap?",
    "What shifts can you do instead?",
    "Pick a matching shift",
    "Good to go!",
];

const NewSwap = () => {
    const { swapIdParam } = useParams();
    const [formStage, setFormStage] = useState(0);
    const [swapId, setSwapId] = useState(swapIdParam || null);
    const [newSwap, dispatchNewSwap] = useReducer(swapReducer, {
        ...initialSwapFormState,
    });

    const [matches, setMatches] = useState(mockMatches);

    const [selectedMatch, setSelectedMatch] = useState(null);
    const [validateHook, newSwapValidationErrors] = useValidateFields(newSwap);

    const fetchHook = useFetch();
    const setStage = (stageIndex) => {
        if (!swapId && stageIndex > 1) {
            setSwapId(Math.round(Math.random() * 100));
        }
        if (stageIndex === "reset") {
            setSwapId(null);
            dispatchNewSwap({ type: "reset" });
        }
        setFormStage(stageIndex === "reset" ? 0 : stageIndex);
    };

    const saveMatch = async () => {
        const matchResponse = await fetchHook({
            type: "addSwap",
            options: { body: newSwap },
        });
        if (matchResponse.success) {
            setStage(3);
        } else {
            setMatches([]);
            dispatchNewSwap({ type: "setSwapMatch" });
            setStage(1);
        }
    };

    useEffect(() => {
        // set matchId of new selected swap
        dispatchNewSwap({ type: "setSwapMatch", payload: selectedMatch });
    }, [selectedMatch]);

    return (
        <div>
            <div className="my-3">
                <div className="d-flex justify-content-center w-100 my-3">
                    <ComponentSlider stage={formStage}>
                        <IconWrap colour="primary">
                            <FaCalendarPlus />
                        </IconWrap>
                        <IconWrap colour="danger">
                            <FaHandHoldingHeart />
                        </IconWrap>
                        <IconWrap colour="warning">
                            <IoIosCart />
                        </IconWrap>
                        <IconWrap colour="success">
                            <FaCalendarCheck />
                        </IconWrap>
                    </ComponentSlider>
                </div>
                <ComponentFader stage={formStage}>
                    {formStageHeaders.map((x) => (
                        <h3
                            key={`stageHeading-${x.id}`}
                            className="text-center my-3">
                            {x}
                        </h3>
                    ))}
                </ComponentFader>
            </div>
            <div className="mx-auto" style={{ maxWidth: "400px" }}>
                <ComponentSlider stage={formStage} stageCounter>
                    <SwapFormWrapper heading="Shift details">
                        <CreateNewSwap
                            setSwapId={setSwapId}
                            newSwap={newSwap}
                            newSwapValidationErrors={newSwapValidationErrors}
                            dispatchNewSwap={dispatchNewSwap}
                            validateFunction={validateHook}
                            setStage={setStage}
                        />
                    </SwapFormWrapper>
                    <SwapFormWrapper heading="Swap in return offers">
                        <p>
                            You can add up to{" "}
                            {smallNumberToWord(5).toLowerCase()} offers, and
                            must have at least one
                        </p>
                        <SwapOffers
                            swapId={swapId}
                            setStage={setStage}
                            newSwap={newSwap}
                            dispatchNewSwap={dispatchNewSwap}
                            setMatches={setMatches}
                        />
                    </SwapFormWrapper>
                    <SwapFormWrapper>
                        <MatchSwap
                            swapId={swapId}
                            setStage={setStage}
                            matches={matches}
                            selectedMatch={selectedMatch}
                            setSelectedMatch={setSelectedMatch}
                            dispatchNewSwap={dispatchNewSwap}
                            saveMatch={saveMatch}
                        />
                    </SwapFormWrapper>
                    <SwapFormWrapper>
                        <ConfirmNewSwap
                            swapId={swapId}
                            setStage={setStage}
                            selectedSwap={selectedMatch}
                            newSwap={newSwap}
                        />
                    </SwapFormWrapper>
                </ComponentSlider>
            </div>
        </div>
    );
};

NewSwap.propTypes = {};

export default NewSwap;

JavaScript is not working when using Bootstrap 5.3

I am building a website on Visual Studio Code and I’m using Bootstrap 5.3, but the functions are not working – buttons not expanding, carousel not rolling, etc. I’m a beginner, so I’ve been struggling to understand why 🙁

Do someone know what’s the issue or had the same problem?

Many thanks!

I used the CDN from here: https://getbootstrap.com/docs/5.3/getting-started/download/

This is what I have in head

*I didn’t start my own JavaScript yet, only have the html and css files.

How to switch next Array index inside Map function javascript?

lets say, I have entry1.number1 and entry1.number2 in a single entry. I need to compare a number with entry1.number2 & entry2.number2.

My code snippet:

useEffect(() => {
    setActiveVehicleIds(activeEntries.map((entry) => (timeFormatter(entry.departure_time) <= sysTime && sysTime <= timeFormatter(entry.arrival_time)
      ? entry.vehicleid
      : false)));
  }, [activeEntries]);

what condition I should write to compare?

Is exporting next js app to static html is cheaper than `next start` option using NodeJS

I’m about to move my Next.js app to production and there are two option for production, with different limitations.

  • next start deploying it on a Node.js server
  • next export hosting static HTML.

Now obviously hosting the static generated HTML is cheaper than deploying it on a Node.js server. But i want to know how much it’s cheaper.

Also, what is the recommended server for deploying a Next.js app using node.js With 1000 users? (how much RAM and CPU)

Server components in Nextjs 13 are not displaying the correct param value passed in the dynamic route (i.e. /user/[id]) doesn’t give correct id passed

I’m using Nextjs 13, I have a client component that routes to /movies/[movieId]. This is the dynamic server component on the [movieId] page:

async function getMovie(id) {
  const movie = await fetch(
    `https://api.themoviedb.org/3/movie/${id}?api_key=${process.env.API_KEY}&language=en-US&append_to_response=videos,people`,
    { cache: "force-cache" }
  );

  return movie.json();
}

const Page = async (props) => {
  // ** ISSUE IS HAPPENING WITH THE props VALUE **

  const movie = await getMovie(props.params.movieId);

  return (
    <div className="container m-auto">{<Movie movie={movie} />}</div>
  );
};

export default Page;

In the code above I show where the error is happening. The problem is, the props property is showing a value of:

{ params: { movieId: ‘%5BmovieId%5D‘ }, searchParams: { movieId: ‘[movieId]’ }}}

The movieId is giving me an encoded value that I’ve tried to decode with decodeURIComponent(). movieId should give me a 6-digit value (i.e. 198409) instead of %5BmovieId%5D.

I’ve tried searching through the beta docs of Nextjs 13 but I’ve found nothing on this.

Does anyone know how to get the actual value dynamic value that is passed in the url?

How do I fix this cocktail shaker sort code to work?

I’m trying to write a code that sorts random numbers with different sorting alrorithms. I have 5 algorithms so far, including bubble sort, javascript built in sort, insertion sort, selection sort, and cocktail sort. I am also writing how many swaps and how much time each sort takes. Other sorts are working just fine( I think), but it seems like cocktail sort is not working.

I tried to modify that part of the code, but none of them worked. Here is the code below. I want it to work properly while displays how many swaps and how much time it took at the console. Thank you.

'NUM_ELEMENTS = 500;
numbers = [];


function setup() {
  createCanvas(400, 300);
  for(i=0;i<=NUM_ELEMENTS;i++) {
    numbers.push(round(random(1,NUM_ELEMENTS)));
  }
  para1 = createElement("p","");
  tempString = "";
  for(i=0;i<=NUM_ELEMENTS;i++) {
    console.log(numbers[i]);
    tempString = tempString + numbers[i] + ",";
  }
  para1.html(tempString);
  button1 = createButton("Bubble Sort");
  button1.mousePressed(bubbleSort);
  button2 = createButton("Seclection Sort");
  button2.mousePressed(selectionSort);
  button3 = createButton("Insertion Sort");
  button3.mousePressed(insertionSort);
  button4 = createButton("Javascript Bulit-in Sort");
  button4.mousePressed(bSort);
}
function bubbleSort() {
  total = 0
  swaps = 0
  t1 = millis();
  console.log("sorting")
  let n = numbers.length;
    
  for(let i = 0; i < n; i++) {
      for(let j = 0; j < n; j++) {
          if(numbers[j] > numbers[j+1]){
            let t = numbers[j];
            numbers[j] = numbers[j+1];
            numbers[j+1] = t;
            swaps = swaps + 1;
            }
        }
    }
  t2 = millis();
  console.log(t2-t1);
  console.log("swaps :",swaps);
}

function selectionSort() { 
  let n = numbers.length;
  console.log("Sorting...")
  total = 0
  t1 = millis();
  swaps = 0
  for(let i = 0; i < n; i++) {
    let min = i;
    for(let j = i+1; j < n; j++){
    if(numbers[j] < numbers[min]) {
     min=j; 
    swaps = swaps + 1;
    }
      }
    if (min != i) {
    let tmp = numbers[i]; 
    numbers[i] = numbers[min];
    numbers[min] = tmp;
    swaps = swaps + 1;
  }
}
  t2 = millis();
  console.log(t2-t1);
  console.log("swaps :", swaps);
}

function insertionSort() {
  console.log("sorting");
  t1 = millis();
  swaps = 0;
  total = 0
  let n = numbers.length;
    for (let i = 1; i < n; i++) {
        let current = numbers[i];
        let j = i-1; 
        while ((j > -1) && (current < numbers[j])) {
            numbers[j+1] = numbers[j];
            swaps = swaps + 1;
            j--;
          }
          numbers[j+1] = current;
      }
  t2 = millis();
  console.log(t2-t1);
  console.log("swaps : ", swaps);
}

function bSort() {
  console.log("Sorting...")
  total = 0
  t1 = millis();
  sort(numbers);
  t2 = millis();
  console.log(t2-t1);
  console.log("swaps : unknown");
}

function cocktailSort() {
  console.log("sorting...")
  total = 0
  swaps = 0
  t1 = millis();
  let n = numbers.length;
  let sorted = false;

  while (!sorted) {
      sorted = true;
      for (let i = 0; i < n - 1; i++) {
          if (numbers[i] > numbers[i + 1]){
              let tmp = numbers[i];
              numbers[i] = numbers[i + 1];
              numbers[i+1] = tmp;
              sorted = false;
          }
  }

  if (sorted)
      break;
  sorted = true;

      for (let j = n - 1; j > 0; j--) {
          if (numbers[j-1] > numbers[j]) {
              let tmp = numbers[j];
              numbers[j] = numbers[j + 1];
              numbers[j+1] = tmp;
              sorted = false;
          }
      }
  }
  t2 = millis();
  console.log(t2-t1);

}


function draw() {
  background(220);
  textSize(13);
  column = 10;
  row = 0;
  for (i=0;i<NUM_ELEMENTS;i++) {
    if (i%18==0) {
      column = column + 18;
      row = 0;
    }
    text(numbers[i],column,row*15+15);
    row++;
  }
  
  
  
 }'