Cannot read property ‘Type’ of undefined

Im having an issue where Im trying to set up Camera Access, but keep getting property ‘Type’ of undefined. I tried using CameraType in the export, but it also said it was undefined when I tried Using CameraType.back. My SDK and expo-camera version are up to date.

Relevant Code:
”’
import { Camera } from “expo-camera”;

const [type, setType] = useState(Camera.Constants.Type.back);

<Camera
style={styles.camera}
type={type} 
ref={setCameraRef}

/>
”’

Problem in browser back button after Keycloak authentication in React application

In my React application when user authenticates with Keycloak, and after redirecting back from Keycloak (React page refreshes), on pressing browser back button the user is not able to navigate to the previous React route and again gets redirected to Keycloak URL.
I have tried the following solutions and all of them work, but after page refreshing (redirecting to Keycloak) none of them work:

I use react-oidc-context.

Solution 1

window.onpopstate = function() {
  navigate("/component1");
}

Solution 2

window.history.pushState({}, '', "/component1");

Solution 3

window.addEventListener("popstate", () => {
  navigate("/component1");
});

I need to mention that, I have tested all the above codes with useEffect, but nothing worked.

Add dots/ellipsis to pagination

I have this working pagination, but I would like to add ellipsis inside the pagination based on the following logic (if maxPages = 3 and total amount of pages is eg. 36):

[1, 2, 3, '...', 36]                 // 1-3 is the current page
[1, '...', 10, 11, 12, '...', 36]    // 10-12 is the current page
[1, '...', 34, 35, 36]               // 34-36 is the current page

How can I modify the pages array to push the ellipsis into it in the right way?

const wrapper = document.querySelector(".wrapper");
const pagination = document.querySelector(".pagination-nav");
const items = Array.from(document.querySelectorAll(".item"));
let filteredItems = items;
let currPage = 1;

/**
 * 
 * @param {int} totalItems Total number of items to paginate
 * @param {int} currentPage Current page
 * @param {int} pageSize Number of items per page
 * @param {int} maxPages Max number of pages to display at the time
 * @returns array of pages
 */
function paginate(totalItems, currentPage = 1, pageSize = 2, maxPages = 3) {

    let totalPages = Math.ceil(totalItems / pageSize);
    if (currentPage < 1) {
        currentPage = 1;
    } else if (currentPage > totalPages) {
        currentPage = totalPages;
    }

    let startPage, endPage;
    if (totalPages <= maxPages) {
        startPage = 1;
        endPage = totalPages;
    } else {
        let maxPagesBeforeCurrentPage = Math.floor(maxPages / 2);
        let maxPagesAfterCurrentPage = Math.ceil(maxPages / 2) - 1;
        if (currentPage <= maxPagesBeforeCurrentPage) {
            startPage = 1;
            endPage = maxPages;
        } else if (currentPage + maxPagesAfterCurrentPage >= totalPages) {
            startPage = totalPages - maxPages + 1;
            endPage = totalPages;
        } else {
            startPage = currentPage - maxPagesBeforeCurrentPage;
            endPage = currentPage + maxPagesAfterCurrentPage;
        }
    }

    let startIndex = (currentPage - 1) * pageSize;
    let endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1);

    let pages = Array.from(Array((endPage + 1) - startPage).keys()).map(i => startPage + i);
    
    console.log(totalItems, currentPage, pageSize, totalPages, startPage, endPage, startIndex, endIndex, pages);
    
    return {
        totalItems: totalItems,
        currentPage: currentPage,
        pageSize: pageSize,
        totalPages: totalPages,
        startPage: startPage,
        endPage: endPage,
        startIndex: startIndex,
        endIndex: endIndex,
        pages: pages
    };
}

function setHTML(items) {
    wrapper.innerHTML = ""
    pagination.innerHTML = ""
    const { totalItems, currentPage, pageSize, totalPages, startPage, endPage, startIndex, endIndex, pages } = paginate(items.length, currPage, 4, 3);

    const ul = document.createElement("ul");
    ul.classList.add('pagination');
    let paginationHTML = "";

    paginationHTML += `<li class="page-item ${currentPage === 1 ? 'disabled' : 'page-prev'}"><a class="page-link" href="#">Previous</a></li>`
    
    pages.forEach(page => {
        if (currentPage === page) {
            paginationHTML += `<li class="page page-item ${currentPage == page ? 'active' : ''}" data-page="${page}"><a class="page-link" href="#" ${currentPage == page ? 'aria-current="page"' : ''}>${page}</a></li>`;
        } else {
            paginationHTML += `<li class="page page-item" data-page="${page}"><a class="page-link" href="#">${page}</a></li>`;
        }
    })

    paginationHTML += `<li class="page-item ${currentPage === endPage ? 'disabled' : 'page-next'}"><a class="page-link" href="#">Next</a></li>`

    ul.innerHTML = paginationHTML;
    pagination.append(ul);

    const start = (currentPage - 1) * pageSize, end = currentPage * pageSize;
    items.slice(start, end).forEach(el => {
        wrapper.append(el)
    })
}

document.addEventListener('click', function (e) {
    const $this = e.target;

    if ($this.parentNode.classList.contains("page")) {
        currPage = parseInt($this.parentNode.getAttribute("data-page"));
        setHTML(filteredItems);
    }
    if ($this.parentNode.classList.contains("page-next")) {
        currPage += 1;
        setHTML(filteredItems);
    }
    if ($this.parentNode.classList.contains("page-prev")) {
        currPage -= 1;
        setHTML(filteredItems);
    }
});

setHTML(filteredItems);
.pagination {
    display: flex;
    padding-left: 0;
    list-style: none;
}

.page-link {
    display: block;
    padding: .375rem .75rem;
}

.active > .page-link {
    background-color: blue;
    color: #fff;
}
<div class="pagination-nav"></div>
<div class="wrapper">
  <div class="item">
    <h3>What is Lorem Ipsum?</h3>
    <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the
      industry's standard dummy text ever since the 1500s.</p>
  </div>
  <div class="item">
    <h3>Why do we use it?</h3>
    <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the
      industry's standard dummy text ever since the 1500s.</p>
  </div>
  <div class="item">
    <h3>Nam porta tempus elit</h3>
    <p>imperdiet dolor, sed convallis lacus sollicitudin at. Integer tempor elementum dolor a fermentum. Sed
      erat
      lorem, tempus mollis mi tincidunt, laoreet faucibus ex.</p>
  </div>
  <div class="item">
    <h3>Pellentesque a tincidunt metus</h3>
    <p>Magna adipisicing labore aute dolore. Officia tempor reprehenderit ad id sunt nisi pariatur. Minim
      ullamco
      aliqua et velit esse veniam.</p>
  </div>
  <div class="item">
    <h3>Tempor irure laboris veniam</h3>
    <p>Ut ad eiusmod adipisicing enim culpa mollit. Do ad adipisicing dolor incididunt dolor ad amet cupidatat.
      Nisi
      minim veniam cillum eu fugiat exercitation ut quis. Mollit velit adipisicing elit qui. Eu in esse elit
      culpa.</p>
  </div>
  <div class="item">
    <h3>Pellentesque a tincidunt metus</h3>
    <p>Magna adipisicing labore aute dolore. Officia tempor reprehenderit ad id sunt nisi pariatur. Minim
      ullamco
      aliqua et velit esse veniam.</p>
  </div>
  <div class="item">
    <h3>Tempor irure laboris veniam</h3>
    <p>Ut ad eiusmod adipisicing enim culpa mollit. Do ad adipisicing dolor incididunt dolor ad amet cupidatat.
      Nisi
      minim veniam cillum eu fugiat exercitation ut quis. Mollit velit adipisicing elit qui. Eu in esse elit
      culpa.</p>
  </div>
  <div class="item">
    <h3>Nostrud id commodo excepteur est</h3>
    <p>Dolore incididunt tempor consectetur deserunt proident id minim exercitation consectetur. Ipsum enim eu
      sit
      duis adipisicing id incididunt. Dolore eu eu sunt nostrud occaecat elit ipsum enim aliquip.</p>
  </div>
  <div class="item">
    <h3>Anim ipsum voluptate ex ex</h3>
    <p>Incididunt qui magna et laborum voluptate amet enim. Ex veniam ipsum sit excepteur. Amet commodo commodo
      labore ipsum ut incididunt. Ipsum et ad adipisicing dolore sit pariatur laboris.</p>
  </div>
  <div class="item">
    <h3>Nostrud id commodo excepteur est</h3>
    <p>Dolore incididunt tempor consectetur deserunt proident id minim exercitation consectetur. Ipsum enim eu
      sit
      duis adipisicing id incididunt. Dolore eu eu sunt nostrud occaecat elit ipsum enim aliquip.</p>
  </div>
  <div class="item">
    <h3>Anim ipsum voluptate ex ex</h3>
    <p>Incididunt qui magna et laborum voluptate amet enim. Ex veniam ipsum sit excepteur. Amet commodo commodo
      labore ipsum ut incididunt. Ipsum et ad adipisicing dolore sit pariatur laboris.</p>
  </div>
  <div class="item">
    <h3>Nostrud id commodo excepteur est</h3>
    <p>Dolore incididunt tempor consectetur deserunt proident id minim exercitation consectetur. Ipsum enim eu
      sit
      duis adipisicing id incididunt. Dolore eu eu sunt nostrud occaecat elit ipsum enim aliquip.</p>
  </div>
  <div class="item">
    <h3>Nostrud id commodo excepteur est</h3>
    <p>Dolore incididunt tempor consectetur deserunt proident id minim exercitation consectetur. Ipsum enim eu
      sit
      duis adipisicing id incididunt. Dolore eu eu sunt nostrud occaecat elit ipsum enim aliquip.</p>
  </div>
  <div class="item">
    <h3>Anim ipsum voluptate ex ex</h3>
    <p>Incididunt qui magna et laborum voluptate amet enim. Ex veniam ipsum sit excepteur. Amet commodo commodo
      labore ipsum ut incididunt. Ipsum et ad adipisicing dolore sit pariatur laboris.</p>
  </div>
  <div class="item">
    <h3>Anim ipsum voluptate ex ex</h3>
    <p>Incididunt qui magna et laborum voluptate amet enim. Ex veniam ipsum sit excepteur. Amet commodo commodo
      labore ipsum ut incididunt. Ipsum et ad adipisicing dolore sit pariatur laboris.</p>
  </div>
  <div class="item">
    <h3>Anim ipsum voluptate ex ex</h3>
    <p>Incididunt qui magna et laborum voluptate amet enim. Ex veniam ipsum sit excepteur. Amet commodo commodo
      labore ipsum ut incididunt. Ipsum et ad adipisicing dolore sit pariatur laboris.</p>
  </div>
  <div class="item">
    <h3>Exercitation id reprehenderit occaecat</h3>
    <p>Consequat minim in duis enim in aliqua elit et. Reprehenderit officia proident est minim fugiat nisi
      laboris
      esse ad. Qui culpa elit deserunt aliquip reprehenderit reprehenderit occaecat. Incididunt nulla irure
      magna
      eiusmod dolor. Cupidatat pariatur cupidatat consequat quis.</p>
  </div>
  <div class="item">
    <h3>Why do we use it?</h3>
    <p>Lorem Ipsum is simply dummy text of the printing and culo typesetting industry. Lorem Ipsum has been the
      industry's standard dummy text ever since the 1500s.</p>
  </div>
  <div class="item">
    <h3>Nam porta tempus elit</h3>
    <p>imperdiet dolor, sed convallis lacus sollicitudin at. Integer tempor elementum dolor a fermentum. Sed
      erat
      lorem, tempus mollis mi tincidunt, laoreet faucibus ex.</p>
  </div>
  <div class="item">
    <h3>Pellentesque a tincidunt metus</h3>
    <p>Magna adipisicing labore aute dolore. Officia hulu tempor reprehenderit ad id sunt nisi pariatur. Minim
      ullamco
      aliqua et velit esse veniam.</p>
  </div>
  <div class="item">
    <h3>Tempor irure laboris veniam</h3>
    <p>Ut ad eiusmod adipisicing enim culpa mollit. Do ad adipisicing dolor incididunt dolor ad amet cupidatat.
      Nisi
      minim veniam cillum eu fugiat exercitation ut quis. Mollit velit adipisicing elit qui. Eu in esse elit
      culpa.</p>
  </div>
  <div class="item">
    <h3>Nostrud id commodo excepteur est</h3>
    <p>Dolore incididunt tempor consectetur deserunt proident id minim exercitation consectetur. Ipsum enim eu
      sit
      duis adipisicing id incididunt. Dolore eu eu sunt nostrud occaecat elit ipsum enim aliquip.</p>
  </div>
  <div class="item">
    <h3>Anim ipsum voluptate ex ex</h3>
    <p>Incididunt qui magna et laborum voluptate amet enim. Ex veniam ipsum sit excepteur. Amet commodo commodo
      labore ipsum ut incididunt. Ipsum et ad adipisicing dolore sit pariatur laboris.</p>
  </div>
  <div class="item">
    <h3>Exercitation id reprehenderit occaecat</h3>
    <p>Consequat minim in duis enim in aliqua elit et. Reprehenderit officia proident est minim fugiat nisi
      laboris
      esse ad. Qui culpa elit deserunt aliquip reprehenderit reprehenderit occaecat. Incididunt nulla irure
      magna
      eiusmod dolor. Cupidatat pariatur cupidatat consequat quis.</p>
  </div>
</div>

Is there a way to edit multiple Ranges made within an element with the “contenteditable” attribute, without breaking them?

I am trying to edit the start and end points for multiple selection Ranges, made within a container with the “contenteditable” attribute set to “true”. However, the mere presence of the attribute causes the selections to break when edited (if more than one is made).

Here is a snippet I made to better illustrate the odd behavior:

    function clicked() {
        const container = document.getElementById("container");
        const selection = window.getSelection();
    
        for (let i = 0; i < selection.rangeCount; i++) {
            const range = selection.getRangeAt(i);
            range.setStart(range.startContainer, 0);
            range.setEnd(range.startContainer, range.startContainer.length);
        }
    }
<h2>With "contenteditable" not enabled</h2>
<div>
    <span>span1</span>
    <span>span2</span>
</div>
<br>
<h2>With "contenteditable" enabled</h2>
<div contenteditable="true">
    <span>span3</span>
    <span>span4</span>
</div>
<br>
<input type="button" onclick="clicked()" value="modify selection(s)">
<br>
<br>
<h3>Tests</h3>
<p>Whilst holding down CTRL, use your cursor to <b>partially</b> select text of:</p>
<ol>
    <li>span1 and span2, then press the button.</li>
    <p><small>(The selections expand correctly.)</small></p>
    <li>span3 and span4, then press the button.</li>
    <p><small>(The selections do not expand correctly.)</small></p>
    <li>span3, then press the button.</li>
    <p><small>(The selection expands correctly.)</small></p>
    <li>span1, span2, span3, and span4, then press the button.</li>
    <p><small>(The selections expand correctly, once again.)</small></p>
</ol>

I want the second test to behave like the others.

Also, just to be clear, I am using a Firefox-based browser, and am making multiple selections by holding down CTRL, whilst click-dragging the cursor (a feature that Chromium browsers seemingly lack).

After polling a server using setinterval, file will download but won’t open in a new tab

I am polling a server, using setInterval, until the pdf’s that I want to download are ready…Once the pdfs are ready to download, I clear the interval, and then I call a function

async function DownloadAndOpenPdf(fileId){
    const ret = await Utilities.PostFunction(DownloadReportFileURL, fileId);
    const blob = new Blob([Base64ToBinary.decodeArrayBuffer(ret.Base64EncryptedData)], { "type": ret.MimeType });
    const link = document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    link.download = ret.FileName + ret.FileExtension;
    link.click();
    window.open(link.href, "_blank");
}

This downloads the pdf, but then I get a message saying that the popup was blocked, however, if I run this function in DevTools the pdf gets downloaded and opens up in a new tab without any issue. If I call that function on a button click event then it works without any issue.
What am I missing? how do I fix this to download and open the file without the message saying that the popup was blocked after an interval has been cleared

Math lib for React Native [closed]

I’m building an app to perform calculations, and I need a library to help me with this.
I want a library to calculate derivatives, but mathjs doesn’t work well with React Native.
Is there another library I can use?

NodeJS with AstraDB consistenly returns error 400 when r/w from Netlify hosted HTML page

I’m working on my firs NodeJS page and have set up to just read and write a string of data when I push a button.
astra.js

const axios = require("axios");
const ASTRA_DB_ID = process.env.ASTRA_DB_ID;
const ASTRA_REGION = process.env.ASTRA_REGION;
const ASTRA_TOKEN = process.env.ASTRA_APP_TOKEN;
const COLLECTION = "test";
const BASE_URL = `https://${ASTRA_DB_ID}-${ASTRA_REGION}.apps.astra.datastax.com/api/rest/v2/keyspaces/default_keyspace/collections/${COLLECTION}`
const HEADERS = {
    "x-cassandra-token": ASTRA_TOKEN,
    "Content-Type": "application/json",
};
exports.handler = async function (event) {
    if (event.httpMethod === "POST") {
        const {_id, message} = JSON.parse(event.body);
        const res = await axios.put(`${BASE_URL}/${_id}`, {_id: _id, message}, {headers:HEADERS});
        return {
            statusCode:200,
            body: JSON.stringify({success:true, res:res.data}),
        };
    } else if (event.httpMethod === "GET") {
        const _id = event.queryStringParameters.id;
        const res = await axios.get(`${BASE_URL}/${_id}`, {headers:HEADERS});
        return {
            statusCode:200,
            body:JSON.stringify(res.data),
        };
    }
    return {statusCode:405, body: "Method Not Allowed"};
}

index.html

<!DOCTYPE html>
<html>
    <head>
        <title>DB TEST</title>
    </head>
    <body>
        <h1>Testing</h1>
        <button id="write-btn">Write to DB</button>
        <button id="read-btn">Read from DB</button>
        <script>
            document.getElementById("write-btn").addEventListener("click", write);
            document.getElementById("read-btn").addEventListener("click", read);
            async function write() {
            alert("test");
            try {
                await fetch('/api/astra', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({_id:'demo', message: 'Hellow from HTML!'})
                });
                alert("Message saved!");
            } catch (e) {
                alert(e)
            }
            }
            async function read() {
                const res = await fetch('/api/astra?id=demo');
                const data = await res.json();
                alert("Message: " + JSON.stringify(data));
            }
        </script>
    </body>
</html>

netlify.toml

[build]
  publish = "public"            
  functions = "functions"  

[[redirects]]
  from = "/api/*"
  to = "/.netlify/functions/:splat"
  status = 200

ASTRA_APP_TOKEN,ASTRA_REGION, and ASTRA_DB_ID are all configured correctly in Netlify environment variables to match the DB. However, whenever I click one of the 2 buttons, it returns:
Writing

(9)[ "AxiosError: Request failed with status code 400", " at settle (/var/task/node_modules/axios/dist/node/axios.cjs:2049:12)", " at IncomingMessage.handleStreamEnd (/var/task/node_modules/axios/dist/node/axios.cjs:3166:11)", " at IncomingMessage.emit (node:events:530:35)", " at endReadableNT (node:internal/streams/readable:1698:12)", " at process.processTicksAndRejections (node:internal/process/task_queues:90:21)", " at Axios.request (/var/task/node_modules/axios/dist/node/axios.cjs:4276:41)", " at process.processTicksAndRejections (node:internal/process/task_queues:105:5)", " at async exports.handler (/var/task/functions/astra.js:14:21)" ]

Reading

(9)[ "AxiosError: Request failed with status code 400", " at settle (/var/task/node_modules/axios/dist/node/axios.cjs:2049:12)", " at IncomingMessage.handleStreamEnd (/var/task/node_modules/axios/dist/node/axios.cjs:3166:11)", " at IncomingMessage.emit (node:events:530:35)", " at endReadableNT (node:internal/streams/readable:1698:12)", " at process.processTicksAndRejections (node:internal/process/task_queues:90:21)", " at Axios.request (/var/task/node_modules/axios/dist/node/axios.cjs:4276:41)", " at process.processTicksAndRejections (node:internal/process/task_queues:105:5)", " at async exports.handler (/var/task/functions/astra.js:21:21)" ]

Both the same error with the exception of returning different lines at which the error occurred, since, of course, reading and writing happens at different lines. Inside the DB I have a default_keyspace labeled as test. The requests are sent, but error when they try to actually fetch/put the data. Anybody know how to fix this?

It is possible in Oracle Apex 24.2 to build something to download/export a table that has SDO_GEOMETRY in shapefile format?

I have tables in Oracle that contain spatial data using the SDO_GEOMETRY data type. I would like to create a button inside APEX that allows users to download a zipped shapefile export of this data. The shapefile should include all the standard files such as .shp, .shx, .dbf, and so on. Is there a way to implement this functionality directly within Oracle APEX?

I tried to manually convert the SDO_GEOMETRY data to shapefile format, but I ran into issues with encoding and generating the correct .dbf, .shx, and .shp files. Due to these complexities, I couldn’t create a proper shapefile export.

What I am looking for is a way to generate a zipped shapefile directly from within Oracle APEX, including all necessary files (.shp, .shx, .dbf, etc.), so users can download and use it easily.

Foreground Shape Doesn’t Fully Cover Background – Black Pixels Visible Through Foreground in Overlapping Elements

I’m working on a layout where two circular div elements overlap exactly — one acting as a black background and the other as a gray foreground — using absolute positioning inside a container. Here’s a simplified version of the code:

<div class="container">
   <div id="background" class="shape"></div>
   <div id="foreground" class="shape"></div>
</div>

And the relevant CSS:

.shape {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    
    backface-visibility: hidden;
    transform: translateZ(0);
    shape-rendering: geometricPrecision;
}

#background {
    background: black;
}

#foreground {
    background: gray;
}

Despite having the foreground element placed on top of the background, some black pixels from the background remain visible around the edges, almost like an aliasing or blending artifact. I tried to address this by adding:

backface-visibility: hidden;
transform: translateZ(0);
shape-rendering: geometricPrecision;

…but these properties did not resolve the issue.
Why are the black pixels still visible, and how can I ensure that the foreground shape fully and cleanly covers the background without those edge artifacts?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    
    <style>
        
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;

            background-color: gray;
        }
        
        .container {
            position: relative;
            display: inline-block;
            
            width: 400px;
            height: 300px; 
        }
        
        .shape {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            border-radius: 50%;
            
            backface-visibility: hidden;
            transform: translateZ(0);
            shape-rendering: geometricPrecision;
        }

        #background {
            background: black;
        }
        
        #foreground {
            background: gray;
        }
        
    </style>

</head>
<body>
    
    <div class="container">
        <div id="background" class="shape"></div>
        <div id="foreground" class="shape"></div>
    </div>
    
</body>
</html>

I am looking for help to solve the issue, not looking for hacks or kind of playing with scale of foreground shape to cover more area than background.

Issue:

enter image description here

Send message to background when popup closes / loses focus

My Chrome extension popup consists of a library of YouTube videos. Each has a “fullscreen” button that when clicked opens a new tab with the YouTube video in fullscreen. This (expectedly) causes the extension popup to close.

For analytics, I want to keep track of when each video gets launched in fullscreen, but my fetch in the onClick handler is failing because the popup closes.

How can I send a message to the background script so that the background can perform the fetch instead of the popup?

Problems with positioning angles when resizing and flipping shapes in HTML5 Canvas

I am developing a web image editor that uses HTML5 Canvas. One of the key features is resizing shapes. To handle sizes correctly, I implemented a ‘flip’ logic that prevents negative width or height. This happens when the user drags a corner to the opposite side, and the sizes newW or newH become negative; in this case, I invert their sign and change the active corner (activeCorner).

The problem arises when, after such a ‘flip’, especially for certain combinations of angles (for example, when moving from bottom-right to bottom-left when flipping along the X-axis, or from bottom-left to top-left when flipping along the Y-axis), the figure shifts sharply or is positioned incorrectly. This leads to jerky size changes. I suspect that the problem lies in the inaccurate recalculation of newX and newY after the size inversion and active angle change.

In addition, I noticed that with rapid repeated ‘flipping’ (when I quickly jerk the corner back and forth, crossing the opposite side), the figure gradually ‘slips’ away from its original position, accumulating errors in the coordinates.

Below is a code snippet responsible for the logic of resizing and flipping the shape. The variables mouseStartX, mouseStartY store the initial mouse coordinates, originalX, originalY, originalWidth, originalHeight store the initial parameters of the shape, and pos stores the current mouse coordinates relative to the canvas. selectedShape.rotation indicates the rotation of the shape (in degrees).

        if (isResizing && (event.buttons & 1)) {
            const rotation = selectedShape.rotation;
            const dx = pos.x - mouseStartX;
            const dy = pos.y - mouseStartY;

            let newX = originalX;
            let newY = originalY;
            let newW = originalWidth;
            let newH = originalHeight;

            const cos = Math.cos(-rotation * Math.PI / 180);
            const sin = Math.sin(-rotation * Math.PI / 180);

            const localDx = dx * cos - dy * sin;
            const localDy = dx * sin + dy * cos;

            let flipX = false, flipY = false;

            if (activeCorner === 'top-left') {
                newW = originalWidth - localDx;
                newH = originalHeight - localDy;

                if (newW < 0) {
                    flipX = true;
                    newW = -newW;
                }
                if (newH < 0) {
                    flipY = true;
                    newH = -newH;
                }

                if (flipX && flipY) {
                    newX = originalX + originalWidth;
                    newY = originalY + originalHeight;
                    activeCorner = 'bottom-right';
                }
                else if (flipX) {
                    newX = originalX + originalWidth;
                    newY = originalY + localDy;
                    activeCorner = 'top-right';
                }
                else if (flipY) {
                    newX = originalX + localDx;
                    newY = originalY + originalHeight;
                    activeCorner = 'bottom-left';
                }
                else {
                    newX = originalX + localDx;
                    newY = originalY + localDy;
                }
            }
            else if (activeCorner === 'top-right') {
                newW = originalWidth + localDx;
                newH = originalHeight - localDy;

                if (newW < 0) {
                    flipX = true;
                    newW = -newW;
                }
                if (newH < 0) {
                    flipY = true;
                    newH = -newH;
                }

                if (flipX && flipY) {
                    newX = originalX - (newW - originalWidth);
                    newY = originalY + originalHeight;
                    activeCorner = 'bottom-left';
                }
                else if (flipX) {
                    newX = originalX - (newW - originalWidth);
                    newY = originalY + localDy;
                    activeCorner = 'top-left';
                }
                else if (flipY) {
                    newX = originalX;
                    newY = originalY + originalHeight;
                    activeCorner = 'bottom-right';
                }
                else {
                    newX = originalX;
                    newY = originalY + localDy;
                }
            }
            else if (activeCorner === 'bottom-left') {
                newW = originalWidth - localDx;
                newH = originalHeight + localDy;

                if (newW < 0) {
                    flipX = true;
                    newW = -newW;
                }
                if (newH < 0) {
                    flipY = true;
                    newH = -newH;
                }

                if (flipX && flipY) {
                    newX = originalX + originalWidth;
                    newY = originalY - (newH - originalHeight);
                    activeCorner = 'top-right';
                }
                else if (flipX) {
                    newX = originalX + originalWidth;
                    newY = originalY;
                    activeCorner = 'bottom-right';
                }
                else if (flipY) {
                    newX = originalX + localDx;
                    newY = originalY - (newH - originalHeight);
                    activeCorner = 'top-left';
                }
                else {
                    newX = originalX + localDx;
                    newY = originalY;
                }
            }
            else if (activeCorner === 'bottom-right') {
                newW = originalWidth  + localDx;
                newH = originalHeight + localDy;

                if (newW < 0) {
                    flipX = true;
                    newW = -newW;
                }
                if (newH < 0) {
                    flipY = true;
                    newH = -newH;
                }

                if (flipX && flipY) {
                    newX = originalX - (newW - originalWidth);
                    newY = originalY - (newH - originalHeight);
                    activeCorner = 'top-left';
                }
                else if (flipX) {
                    newX = originalX - (newW - originalWidth);
                    newY = originalY;
                    activeCorner = 'bottom-left';
                }
                else if (flipY) {
                    newX = originalX;
                    newY = originalY - (newH - originalHeight);
                    activeCorner = 'top-right';
                }
                else {
                    newX = originalX;
                    newY = originalY;
                }
            }

            selectedShape.x = newX;
            selectedShape.y = newY;
            selectedShape.width = newW;
            selectedShape.height = newH;

            if (flipX || flipY) {
                mouseStartX = pos.x;
                mouseStartY = pos.y;
                originalX = newX;
                originalY = newY;
                originalWidth  = newW;
                originalHeight = newH;
            }

            redrawAll();
            updateRectAnglePropertyPanel();
            return;
        }

I suspect that the problem lies in the inaccurate recalculation of newX and newY after inverting the dimensions and changing the active angle.

So far, the shape is a rectangle without rotation.

How can I correctly adjust the newX and newY coordinates (and possibly the logic for changing activeCorner) in the ‘flip’ conditions for a rotated rectangle so that its positioning and resizing remain smooth and accurate, without jumps and accumulation of errors during multiple flips?

If you need additional code, please ask. I am also open to completely changing the resizing logic if you suggest it.

Jest changes JSON while importing?

I’m testing document generation forms using Jest. Each test case uses the same JSON mock that contains an array of two items. When I run the test for a single form, the order of items in the array is correct: [ItemA, ItemB]

However, when I run tests for multiple forms the array appears in a different order: [ItemB, ItemA]

The mock is a static .json file imported like this:

import mockData from '../../path/to/mock.json';

Even when I log mock immediately after import, the order is already incorrect.

Some specs:

  • jest 27.x
  • env jsdom
  • jest.config.js includes only babel-jest in the transform field and does not specify any custom loader for JSON files, also babel-jest doesnt touch JSON files

Why does the order of elements in the array change depending on how many test cases I run?

What can I do to guarantee that the array is always loaded in the correct order?

React Search Page Not Fetching Blogs from Render-Hosted Express + MongoDB Backend

I’ve deployed a MERN stack news portal to Render:

Frontend: https://news-portal-f.onrender.com

Backend: https://news-portal-jzcd.onrender.com

The backend uses Express and connects to MongoDB Atlas, and exposes an endpoint /blogs that should return all blog entries. On the frontend, I have a SearchResults component that fetches the data, filters it based on a search query, and displays the matching results.

However, my search results page is stuck at “Loading…” or sometimes prints “No results found” — even though the backend works fine when I hit it directly via Postman.

What I’ve Tried:
Accessing https://news-portal-jzcd.onrender.com/blogs manually in browser → returns JSON ✔️

Checked CORS setup on backend: origin is correctly set to frontend domain ✔️

Console logs in backend show no requests hitting /blogs from frontend ❌

Tried both using process.env.REACT_APP_BACKEND_URL and hardcoded backend URL

No major frontend error logs, but request sometimes just hangs or fails silently

  origin: "https://news-portal-f.onrender.com"
}));

app.get("/blogs", async (req, res) => {
  const blogs = await Blog.find();
  res.json({ blog: blogs });
});
  const backendUrl = process.env.REACT_APP_BACKEND_URL || "https://news-portal-jzcd.onrender.com";

  fetch(`${backendUrl}/blogs`)
    .then(res => res.json())
    .then(data => {
      setBlogs(data.blog);
      setLoading(false);
    })
    .catch(err => {
      console.error("Error fetching blogs:", err);
      setLoading(false);
    });
}, []);

My Questions:
Is there a known issue with Render that blocks frontend-to-backend requests across subdomains?

Do I need to prefix /blogs with /api or structure routes differently?

Could this be an async deployment issue (Render’s cold start)? Do I need retries or pre-warmers?

Any other tips to debug why frontend is not hitting backend despite proper CORS and correct URL?

React frontend not connecting to Express backend deployed on Render – CORS issue or endpoint mismatch?

I’m building a news portal with a React frontend and an Express backend. Both are deployed on Render:

Frontend: https://news-portal-f.onrender.com

Backend: https://news-portal-jzcd.onrender.com

I’m trying to send a POST request from a form in React to /add-blog endpoint in Express. But the request doesn’t seem to reach the backend.

import axios from "axios";
import { useState } from "react";

function AddBlog() {
  const [title, setTitle] = useState("");
  const [content, setContent] = useState("");

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      await axios.post("https://news-portal-jzcd.onrender.com/add-blog", {
        title,
        content,
      });
      alert("Blog added!");
    } catch (err) {
      console.error("Error:", err);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input value={title} onChange={(e) => setTitle(e.target.value)} />
      <textarea value={content} onChange={(e) => setContent(e.target.value)} />
      <button type="submit">Submit</button>
    </form>
  );
}
const express = require("express");
const cors = require("cors");
const app = express();

app.use(cors({
  origin: "https://news-portal-f.onrender.com"
}));
app.use(express.json());

app.post("/add-blog", (req, res) => {
  console.log(req.body); // Doesn't get logged
  res.json({ message: "Blog added" });
});

What I’ve Checked So Far:
CORS is set up with the correct frontend origin.

POST request URL in React is correct.

Backend logs show no request reaching /add-blog.

No obvious error in browser console (but request might hang or fail silently).

Network tab in Chrome shows the request is pending or fails with 404.

My Questions:
Is there anything I’m missing in the way React or Express is deployed on Render?

Could this be a route mismatch or something to do with how Render handles server URLs?

Is /add-blog correctly configured or should I prefix it with /api or something else?