How to inner text from a span on Playwright?

In span I have number and try to inner text for my test and I can’t do it. I need to check I have 0 or another count of staff and I don’t see result of num_basket in console

<span class="basket-count-items badge badge-primary">1</span>
const num_basket = await page.locator('.basket-count-items.badge').textContent()
 console.log(num_basket)
 if (num_basket !== 0) {await page.locator('//a[@id="dropdownBasket"]').click()
 await page.locator('.btn.btn-danger').click()}

How I can inner text?

java use with java script by using teavm webassembly [closed]

I tried to pass String from javascript to java. And In java code it has some operations. but it give error.

const inputStrPointer = createTeaVMString(input);
const outputStrPointer = teaVM.instance.exports.process(inputStrPointer);
const result = extractString(outputStrPointer);

here the createTeaVMString is like this,

function createTeaVMString(input) {
const strPointer = teaVM.allocateString(input.length);
const strDataPtr = teaVM.stringData(strPointer);
const charArrayPtr = teaVM.objectArrayData(strDataPtr);
const memory = new Uint16Array(teaVM.memory.buffer, charArrayPtr, input.length);
for (let i = 0; i < input.length; i++) {
memory[i] = input.charCodeAt(i);
}
return strPointer;
}

and the exactTeaVMString is like this,

function extractString(strPointer) {
//pointer
    const stringDataPtr = teaVM.stringData(strPointer);
    const length = teaVM.arrayLength(stringDataPtr);
    const charArrayPtr = teaVM.charArrayData(stringDataPtr);
    const memory = new Uint16Array(teaVM.memory.buffer, charArrayPtr, length);
    let result = "";
    for (let i = 0; i < length; i++) {
        result += String.fromCharCode(memory[i]);
    }
    return result;
}

But in the java code,

@Export(name = "process")
public static String process(String input) {

    return new StringBuilder(input).reverse().toString();

}

@Export(name = "type")
public static String type(String input) {
    return  input.toString().getClass().getSimpleName();
}

First process function is working, but second one is not(type).
And I tried lots of these kind of functions. I tried to look references but there are no any references. Then by using AI it tells that js String is not fully converted to java String.

Dynamic tab content from hidden div not rendering reliably with jQuery on PHP page

I’m building a PHP page with multiple tabs (Termijnen, Mandaten, and Admin). Each tab’s content is pre-rendered by PHP inside hidden <div> elements. I then inject the content into a visible container (#tab-content) using jQuery when a tab is clicked.

Here’s the structure of my HTML:

<div id="content-termijnen" style="display:none;">
    <div class="row g-3">
        <?php foreach($termijnen as $t): 
            $statusClass = match($t['status']) {
                'pending' => 'bg-warning text-dark',
                'betaald' => 'bg-success text-white',
                'achterstallig' => 'bg-danger text-white',
                default => 'bg-light text-dark',
            };

            $mandaatNummer = null;
            if (!empty($t['mandaat_id'])) {
                $stmt = $conn->prepare("SELECT mandaat_nummer FROM contributie_mandaten WHERE id = ?");
                $stmt->bind_param("i", $t['mandaat_id']);
                $stmt->execute();
                $stmt->bind_result($mandaatNummer);
                $stmt->fetch();
                $stmt->close();
            }
        ?>
        <div class="col-md-6 col-lg-4">
            <div class="card h-100 shadow-sm">
                <div class="card-body d-flex flex-column justify-content-between">
                    <div>
                        <h5 class="card-title">Termijn #<?= $t['id']; ?></h5>
                        <p class="card-text">
                            Bedrag: €<?= number_format($t['bedrag'], 2, ',', '.'); ?><br>
                            Vervaldatum: <?= date('d-m-Y', strtotime($t['vervaldatum'])); ?><br>
                            <?php if ($mandaatNummer): ?>
                                <span class="badge bg-success">Mandaat: #<?= htmlspecialchars($mandaatNummer); ?></span>
                            <?php else: ?>
                                <span class="badge bg-warning">Geen mandaat gekoppeld</span>
                            <?php endif; ?>
                        </p>
                        <span class="badge <?= $statusClass; ?>"><?= ucfirst($t['status']); ?></span>
                    </div>
                    <div class="mt-3 d-flex gap-2 flex-wrap">
                        <button class="btn btn-sm btn-primary btn-link-mandate" data-termijn-id="<?= $t['id']; ?>">Koppel Mandaat</button>
                        <button class="btn btn-sm btn-outline-primary btn-incasso" data-id="<?= $t['id']; ?>" data-bedrag="<?= number_format($t['bedrag'], 2, ',', '.'); ?>" data-vervaldatum="<?= date('d-m-Y', strtotime($t['vervaldatum'])); ?>">Genereer Incasso</button>
                        <button class="btn btn-sm btn-outline-secondary btn-invoice">Genereer Factuur</button>
                    </div>
                </div>
            </div>
        </div>
        <?php endforeach; ?>
    </div>
</div>

<div id="content-mandaten" style="display:none;">
    <div class="mb-3">
        <button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#createMandateModal">
            Nieuw Mandaat Aanmaken
        </button>
    </div>
    <div class="row g-3">
        <?php foreach($mandaten as $m): 
            $statusClass = match($m['status']) {
                'pending' => 'bg-warning text-dark',
                'actief' => 'bg-success text-white',
                'gepauzeerd' => 'bg-danger text-white',
                'ingetrokken'=> 'bg-danger text-white',
                default => 'bg-light text-dark',
            };
            $ibanPlain = decryptIban($m['iban'], $encKey, $authKey);
        ?>
        <div class="col-md-6 col-lg-4">
            <div class="card h-100 shadow-sm">
                <div class="card-body d-flex flex-column justify-content-between">
                    <div>
                        <h5 class="card-title">Mandaat #<?= $m['mandaat_nummer']; ?></h5>
                        <p class="card-text">IBAN: <?= htmlspecialchars($ibanPlain !== null ? $ibanPlain : 'Ongeldig'); ?></p>
                        <span class="badge <?= $statusClass; ?>"><?= ucfirst($m['status']); ?></span>
                    </div>
                    <div class="mt-3 d-flex gap-2 flex-wrap">
                        <button class="btn btn-sm btn-outline-primary btn-iban" data-id="<?= $m['id']; ?>">Wijzig IBAN</button>
                        <button class="btn btn-sm btn-primary btn-pause" data-id="<?= $m['id']; ?>">Pauzeer</button>
                        <button class="btn btn-sm btn-outline-primary">Intrekken</button>
                        <button class="btn btn-sm btn-success btn-link-term" data-mandaat-id="<?= $m['id']; ?>">Koppel aan Termijn</button>
                    </div>
                </div>
            </div>
        </div>
        <?php endforeach; ?>
    </div>
</div>

<div id="content-admin" style="display:none;">
    <div class="mb-4">
        <button class="btn btn-primary mb-3" data-bs-toggle="modal" data-bs-target="#planModal">Nieuw Plan Aanmaken</button>
        <div class="row g-3">
            <?php foreach($plannen as $p): 
                $statusClass = match($p['status']){
                    'actief' => 'bg-success text-white',
                    'draft' => 'bg-warning text-dark',
                    default => 'bg-secondary text-white'
                };
            ?>
            <div class="col-md-6 col-lg-4">
                <div class="card h-100 shadow-sm">
                    <div class="card-body d-flex flex-column justify-content-between">
                        <div>
                            <h5 class="card-title"><?php echo $p['naam']; ?> €<?php echo number_format($p['bedrag'],2,',','.'); ?></h5>
                            <p class="card-text">Start: <?php echo date('d/m/Y', strtotime($p['startdatum'])); ?><?php if($p['einddatum']) echo ' - Eind: '.date('d/m/Y', strtotime($p['einddatum'])); ?></p>
                            <span class="badge <?php echo $statusClass; ?>"><?php echo ucfirst($p['status']); ?></span>
                        </div>
                        <div class="mt-3 d-flex gap-2">
                            <button class="btn btn-sm btn-outline-primary"><i data-feather="edit-2"></i> Bewerk</button>
                            <button class="btn btn-sm btn-outline-danger"><i data-feather="trash-2"></i> Verwijder</button>
                        </div>
                    </div>
                </div>
            </div>
            <?php endforeach; ?>
        </div>
    </div>
</div>

The tabs themselves are buttons:

<div class="button-group" role="group">
    <button class="btn btn-sm btn-outline-primary active" data-tab="termijnen">Termijnen</button>
    <button class="btn btn-sm btn-outline-primary" data-tab="mandaten">Mandaten</button>
    <button class="btn btn-sm btn-outline-secondary" data-tab="admin">Admin</button>
</div>

JavaScript to load tabs:

function loadTab(tab) {
    const content = $(`#content-${tab}`).html();
    $('#tab-content').html(content);

    if (window.feather) feather.replace(); // for icons
}

I also have search, pagination, and dynamic modals for editing IBANs, pausing mandates, linking mandates to termijnen, etc.

Problem

  • The hidden for Termijnen exists ($(‘#content-termijnen’).length === 1) and contains HTML, but is not visible in the #tab-content container when expected.
  • The hidden s for Mandaten and Admin currently do not exist in the DOM at all when inspected with jQuery ($(‘#content-mandaten’).length === 0).
  • Console logs show that the Termijnen HTML exists, but it does not render initially.
  • Mandaten only exists dynamically if a button is clicked that makes it active.
  • A simple console.log(‘Hello world’); works, so scripts run, but the tab content injection does not appear as expected.
  • All libraries (jQuery, Bootstrap, Feather) are loaded, and no JS errors are present.

Question

  1. Why does content from hidden <div>s sometimes not render when injected into #tab-content, even though the <div> exists and has HTML?
  2. How can I reliably load all tab content immediately on page load or on tab click, so that the dynamic cards, modals, and icons work correctly without requiring extra user interaction?

I tried to render the hidden tab content <div>s (#content-termijnen, #content-mandaten, and #content-admin) into the main container #tab-content using jQuery when the page loads or when a tab button is clicked.

  • I verified that $('#content-termijnen').length === 1 and it contains HTML, so I expected it to appear inside #tab-content on page load.
  • I also verified that console.log('Hello World') in a separate <script> tag works, proving that scripts execute.
  • I expected the Termijnen tab to load automatically, and Mandaten/Admin tabs to populate when their respective buttons are clicked.

Actual results

  • Termijnen HTML exists in the DOM but does not appear in #tab-content, so the content is invisible.
  • Mandaten and Admins are 0 in length initially and do not appear at all.
  • No JavaScript errors occur, and libraries like jQuery and Feather are loaded initially.

Changing a saved image in a gallery by setting state

I am building a simple gallery application. I want to be able to change the main gallery image to a different image when it is clicked using state but am having difficulty. All the images are saved directly in the src folder. In my current code when you select a new image to display the current one disappears but does not change to the selected one, but I can’t make it work. Strangely when I pass a variable directly into the src parameter it works, but not when I do it with state, e.g.:

src={clickedImageId !== "4" ? img2 : img4}

This is my code. Where am I going wrong?

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import { useState } from "react";
import img1 from "./img1.jpg";
import img2 from "./img2.jpg";
import img3 from "./img3.jpg";
import img4 from "./img4.jpg";

function App() {
  const [clickedImageId, setClickedImageId] = useState("4");
  const [galleryImg, setGalleryImg] = useState(img4);


  function handleClick(e) {
    setClickedImageId(e.target.id);
    setGalleryImg(`img${e.target.id}`);
    console.log(galleryImg, clickedImageId);

    return;
  }

  return (
    <div className="container">
      <div className="gallery">
        <img
          className="img1"
          id="1"
          src={img1}
          onClick={handleClick}
          alt="clouds in blue sky"
        />{" "}
        <img
          className="img2"
          id="2"
          src={img2}
          onClick={handleClick}
          alt="two boys rowing a boat"
        />{" "}
        <img
          className="img3"
          // className={clickedImageId === "3" ? "clicked-img" : "img3"}
          id="3"
          src={img3}
          onClick={handleClick}
          alt="tree in orange dusk"
        />
        <img
          className="img4"
          id={"4"}
          src={clickedImageId !== "4" ? galleryImg : img4}
          onClick={handleClick}
          alt="rocks on the beach"
        />
      </div>
    </div>
  );
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

I am struggling with making shared header/footer elements in HTML

I am making a website and I want to build a common header and footer to use on each page that I can define somewhere else, rather than on each individual page. I’ve seen a few different methods that claim to work to take a file I wrote to define my header and footer, and then add it to each page though a function or a script.

The last method I tried extended the HTMLElement into new classes, and then defined those elements with a customElements.define() function, but when I refresh the page I don’t see any output from the .js file.

This is the modules.js file I wrote to define the header and the footer:

class CommonHeader extends HTMLElement {
    connectedCallBack() {
        this.innerHTML = '
        <p style="display: flex; justify-content: space-around; background-color: #eeeeee; padding: 10px;">
            <a href="./index.html">Home</a>
            <a href="./mission.html">Mission</a>
            <a href="./News/news.html">News</a>
            <a href="./Programs/programs.html">Programs</a>
            <a href="./Blog/blog.html">Blog</a>
        </p>
        '
    }
}
class CommonFooter extends HTMLElement {
    connectedCallBack() {
        this.innerHTML = '
        <p style="display: flex; justify-content: space-around; background-color: #eeeeee; padding: 10px;">Copyright &copy;2025; Designed by Sapientiae Domus</p>
        '
    }
}
customElements.define('common-header', CommonHeader)
customElements.define('common-footer', CommonFooter)

And this is the template.html file I’m trying to test with so I can copy this to make the skeleton for each page:

<!DOCTYPE html>
<html lang="en">
<link rel="stylesheet" href="/style.css">

<head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width">
        <title>Sapientiae Domus</title>
</head>

<body>
        <common-header></common-header>
        <h1>Sapientiae Domus</h1>
        <p>This is a home page...</p>
        <common-footer></common-footer>
        <script src="./modules.js"></script>
        <p style="display: flex; justify-content: space-around; background-color: #eeeeee; padding: 10px;">Copyright &copy;
                2025; Designed by Sapientiae Domus</p>
</body>

</html>

I have a script that runs to set up a local web server to host the site on my machine because I read that certain functions wouldn’t call the right way if you simply use the browser to search the files.

When I check the console on the webpage I get this message: "Uncaught SyntaxError: '' string literal contains an unescaped line break" with modules.js:3:20 in the corner of the error box. I tried looking it up, and what I found said to break the lines putting each into a string and following them with a ‘+’ to add them together but I couldn’t make that work properly either. I undid that and put the code in the format the example was given in, and that’s what is shown above.

Typed property AppEntityX:X must not be accessed before initialization

I’m trying to upgrade my Symfony from 5.4 to 6.4 and PHP from 7.4 to 8.4. I almost did all changes but I’m currently blocked on this exception :

Typed property AppEntityAppRole::$uniqid must not be accessed before initialization

I already did my researchs and found that private properties must be initialized, so this is what I did :

#[ORMColumn(name: "uniqid", type: "string", length: 50, nullable: false)]
private ?string $uniqid = null;
public function getUniqid(): ?string
{
    return $this->uniqid;
}

public function setUniqid(string $uniqid): self
{
    $this->uniqid = $uniqid;

    return $this;
}

So I don’t understand where comes my error ?

The error trace shows that it comes from the findAll() repository function.

Did I missed something ?

I also cleared the cache but does nothing.

Thanks

Does Xero not provide an API or built-in function to fetch daily data? [closed]

We have a custom system, and we are trying to integrate Xero’s daily sales data into this system. But we are unable to do that.
I would like to confirm whether Xero provides any API or built-in functionality that allows us to fetch daily data (such as daily sales, transactions, or other relevant reports). From my current exploration, I could not find such an option, but I wanted to double-check with your team in case I may have overlooked it.

If this feature is not available, could you kindly suggest an alternative approach or workaround to achieve daily data extraction from Xero?

API failed to open stream: connection refused [closed]

After installing web application, I added the api key to the built in setting in the admin dashboard. The api was calling and getting data, the next day I get an error code saying “failed to open stream: connection refused? cleared cache and dug into the files and nothing seems to be wrong on the app. Its using File_get_contents

So if it was working yesterday, but not today? I am guessing the server or something or something is blocking it. Unless I was sleepwalking and accidently changed a code while in my sleep?

anyone got any ideas?

Netsuite PHP find Sales Order using custom field

Kind of embarrassed to post this here, but I’m at my wits end. I am trying to pull up a Sales Order in Netsuite, searching on a custom filed and using the PHP ToolKit, but have hit a brick wall. I’ve searched records on custom fields before and haven’t had an issue, but this time I’m getting no results. This custom field is a place where we store an outside order number (like if the order came from Amazon or eBay) and I can pull up the record inside of Netsuite (using the GUI) with this custom field. Currently my code looks like this:

$ts = new TransactionSearch();
$tsb = new TransactionSearchBasic();
$oth = new SearchStringCustomField();
$oth->internalId = 69;
$oth->searchValue = '700184356';
$oth->operator = 'is';
$cfl = new SearchCustomFieldList();
$cfl->customField = array($oth);
$tsb->customFieldList = $cfl;
$ts->basic = $tsb;
$request = new SearchRequest();
$request->searchRecord = $ts;
$response = $ns->search($request);

I’ve double and triple checked the id of the custom field and also tried using its name instead of id ($oth->scriptId = 'custbody_custbody_storefront_order'). I get no errors, but also no records are returned. I’m hoping an extra set of eyes can spot what I’m doing wrong.

Custom field name

Filament v4 migration – Livewire SupportValidation error and login redirect not working

I am migrating a project and found an issue I can’t resolve.
Here are the details:

Versions after migration
Filament: v4.0 (from v3.2.117)
PHP: 8.3 (from 8.2)
Laravel: 12.26.3 (from 11.44.0)
Livewire: 3.6.4 (from 3.5.6)

Problem
When loading the login route, I get the following error:

local.ERROR: IlluminateSupportViewErrorBag::put(): 
Argument #2 ($bag) must be of type IlluminateContractsSupportMessageBag, null given, 
called in /vendor/livewire/livewire/src/Features/SupportValidation/SupportValidation.php on line 21

Trace points to SupportValidation->render() and ViewErrorBag->put() receiving null instead of a MessageBag.

Temporary workaround
To bypass this, I temporarily patched SupportValidation and SupportTesting in the vendor/ folder so that a new MessageBag instance is created when getErrorBag() is null. Example (simplified):

if (! $bag instanceof MessageBag) {
    $bag = new MessageBag((array) $bag);
    if (method_exists($this->component, 'setErrorBag')) {
        $this->component->setErrorBag($bag);
    }
}

**With this hack:

The login page renders correctly.

Authentication works (confirmed via browser dev tools and Laravel logs).

But the redirect after login does not happen** — the user stays on the login page even though authentication is successful.

What I tried:

  • Verified that the user is authenticated (Auth::check() returns true).

  • Logs confirm login success (tail -f storage/logs/laravel.log).

  • Without patching the vendor files, the login page never renders (due to the null MessageBag error).

  • With patching, page renders but redirect is broken.

Questions

1 – Is this a known issue with Filament v4 + Livewire 3.6.x during login?

2 – Should I be initializing the MessageBag in a different way rather than patching vendor code?

3 – Why would the redirect fail even though authentication succeeds?

Unfortunately, my project is private, but I can try to create a minimal reproduction repo if needed.

Any help or guidance would be appreciated.

Form.io DataGrid custom pager component: Select component value resets when switching pages

I am building a custom DataGrid pager component in Form.io to allow pagination inside grids. The pager works correctly for all components (text fields, checkboxes, etc.), except for Select components (I’m using Angular 19.2.0, @formio/angular: ^9.0.0, formiojs: ^4.21.7)

The issue happens when I add a Select component to a row in the DataGrid and then navigate between pages. The Select value flickers or resets, usually defaulting to the first available option, even though the underlying data is correct.

For example:
DataGrid (pageLimit = 3)

TextField Select
1 A
2 B
3 C
4 D

On Page 1, I see rows 1–3 (A, B, C) correctly.

When I go to Page 2, I expect to see row 4 (D), but instead the TextField shows 4 and the Select shows A (the first option), instead of D.

I confirmed that the data itself is fine by logging allGridRows and the values are stored correctly. The problem is only with the UI rendering of the Select component when switching pages.

So far, I tried debugging by checking how values are passed when re-rendering the grid, but I can’t figure out why the Select component specifically loses its correct value, while other components keep theirs.

I’ve gone through the Form.io source code for the Select component to understand how it handles rendering and value persistence. However, I couldn’t find anything that directly explains why the Select value resets only when used inside my custom DataGrid pager, maybe it’s a skill issue.

Other components (like text fields) render correctly across pages, so this issue seems to be specific to Select.

I also verified that:

  1. The data itself is correct (via console.log(allGridRows)), so the problem isn’t in the storage.
  2. The issue happens only in the UI re-rendering when switching pages.
  3. Manually editing rows (like setting 4 → D) stores the correct value, but the Select resets when navigating back to that page.

This is my code (see: in app.component.ts, submissionData has Dal in the 4th row, but in the table Aban is showing in the 4th row. Try changing the Select component data and moving between pages): StackBlitz Example

Since my custom pager is meant to support multiple component types inside DataGrids, I need Select to behave consistently with other components. Right now, the UI resetting breaks the user experience and makes it seem like data was lost, even though it’s still stored.

I believe the issue comes from how FormIO renders Select component values (specifically how setValue works), rather than from the logic in my DataGridPager implementation (DataGridPager.js):

import { Formio } from "@formio/js";
import editForm from "./DataGridPager.form.js";

const Component = Formio.Components.components.component;

export default class DataGridPager extends Component {
    static editForm = editForm;

    static schema(...extend) {
        return Component.schema(
            {
                type: "dataGridPager",
                label: "Data Pager",
                key: "dataGridPager",
                pageLimit: 5,
                gridToAttach: "",
            },
            ...extend
        );
    }

    static get builderInfo() {
        return {
            title: "Data Grid Pager",
            icon: "list",
            group: "basic",
            weight: -100,
            schema: DataGridPager.schema(),
        };
    }

    constructor(component, options, data) {
        super(component, options, data);

        this.pageLimit =
            Number(this.component.pageLimit) > 0
                ? Number(this.component.pageLimit)
                : 5;
        this.currentPageNum = 1;
        this.totalPagesNum = 1;
        this.totalRowsNum = 1;
        this.allGridRows = [];
        this.targetComponent = null;
    }

    render() {
        return super.render(this.renderTemplate("dataGridPager"));
    }

    /**
     * Called after render; wires refs, finds target component, and initializes UI.
     */
    attach(element) {
        // Let base class attach first
        super.attach(element);

        // Load refs from template
        this.loadRefs(element, {
            dataGridPager: "single",
            firstItemNum: "single",
            lastItemNum: "single",
            totalItemsNum: "single",
            currentPageNum: "single",
            totalPagesNum: "single",
            firstBtn: "single",
            prevBtn: "single",
            nextBtn: "single",
            lastBtn: "single",
        });

        // Locate the grid/etc to attach to
        this.targetComponent = this.findTargetComponent();

        // If not found, show zero state and disable buttons
        if (!this.targetComponent) {
            this.allGridRows = [];
            this.computeTotals();
            this.updateUI();
            this.setButtonsDisabled(true);
            return;
        }

        // Verify it's actually a data grid component
        if (this.targetComponent.component.type !== "datagrid") {
            console.warn(
                `DataGridPager: Component "${this.component.gridToAttach}" is not a data grid`
            );
            this.refs.dataGridPager.innerHTML = `<div>Error: Attached component is not a data grid</div>`;
            this.allGridRows = [];
            this.computeTotals();
            this.updateUI();
            this.setButtonsDisabled(true);
            return;
        }

        // Compute totals and clamp current page
        this.computeTotals();

        // Wire button click handlers (store references for cleanup)
        this._firstHandler = () => this.goToPage(1);
        this._prevHandler = () => this.goToPage(this.currentPageNum - 1);
        this._nextHandler = () => this.goToPage(this.currentPageNum + 1);
        this._lastHandler = () => this.goToPage(this.totalPagesNum);

        if (this.refs.firstBtn)
            this.refs.firstBtn.addEventListener("click", this._firstHandler);
        if (this.refs.prevBtn)
            this.refs.prevBtn.addEventListener("click", this._prevHandler);
        if (this.refs.nextBtn)
            this.refs.nextBtn.addEventListener("click", this._nextHandler);
        if (this.refs.lastBtn)
            this.refs.lastBtn.addEventListener("click", this._lastHandler);

        // Listen for changes inside the target component so edits persist across pages.
        // Not all component implementations expose on/off; guard those calls.
        this._targetChangeHandler = () => {
            // read the current visible page rows from the target and merge them back
            const currentPageData = Array.isArray(this.targetComponent.dataValue)
                ? JSON.parse(JSON.stringify(this.targetComponent.dataValue))
                : [];

            const offset = (this.currentPageNum - 1) * this.pageLimit;
            // Remove the old slice and replace with new
            this.allGridRows.splice(offset, this.pageLimit, ...currentPageData);

            // Recompute totals in case rows were added/removed
            this.computeTotals();

            // If this page exceeds the limit, move to next page
            if (currentPageData.length > this.pageLimit) {
                this.goToPage(this.currentPageNum + 1);
            } else {
                // Otherwise just refresh this page
                this.goToPage(this.currentPageNum);
            }
        };

        this._targetDeleteHandler = () => {
            // read the current visible page rows from the target and merge them back
            const currentPageData = Array.isArray(this.targetComponent.dataValue)
                ? JSON.parse(JSON.stringify(this.targetComponent.dataValue))
                : [];

            if (currentPageData.length === 0 && this.currentPageNum > 1) {
                // If we deleted the last item on this page, move back a page
                this.currentPageNum--;
                this.allGridRows.pop();
            } else {
                const offset = (this.currentPageNum - 1) * this.pageLimit;
                // Remove the old slice and replace with new
                this.allGridRows.splice(offset, this.pageLimit, ...currentPageData);
            }

            // Recompute totals in case rows were added/removed
            this.computeTotals();

            this.goToPage(this.currentPageNum);
        };

        if (typeof this.targetComponent.on === "function") {
            this.targetComponent.on("change", this._targetChangeHandler);
            this.targetComponent.on("dataGridDeleteRow", this._targetDeleteHandler);
        } else if (typeof this.targetComponent.addEventListener === "function") {
            // fallback (rare)
            this.targetComponent.addEventListener(
                "change",
                this._targetChangeHandler
            );
            this.targetComponent.addEventListener(
                "dataGridDeleteRow",
                this._targetDeleteHandler
            );
        }

        // Show initial page
        this.goToPage(this.currentPageNum);
    }

    /**
     * Find the target component by key (searches recursively from root)
     */
    findTargetComponent() {
        if (!this.root || !this.component?.gridToAttach) return null;
        try {
            return this.root.getComponent(this.component.gridToAttach);
        } catch (e) {
            return null;
        }
    }

    /**
     * Recalculate totals and clamp current page
     */
    computeTotals() {
        this.totalRowsNum = Array.isArray(this.allGridRows)
            ? this.allGridRows.length
            : 1;
        this.totalPagesNum = Math.max(
            1,
            Math.ceil(this.totalRowsNum / this.pageLimit)
        );
        if (this.currentPageNum < 1) this.currentPageNum = 1;
        if (this.currentPageNum > this.totalPagesNum)
            this.currentPageNum = this.totalPagesNum;
    }

    /**
     * Show a specific page: slice items, set target value, update UI
     */
    goToPage(pageNum) {
        if (!this.targetComponent) return;

        // ensure pageNum is always between 1 and totalPagesNum
        const currentPageNum = Math.max(
            1,
            Math.min(pageNum || 1, this.totalPagesNum)
        );
        this.currentPageNum = currentPageNum;

        const start = (currentPageNum - 1) * this.pageLimit;
        const end = start + this.pageLimit;
        const pageSlice = this.allGridRows.slice(start, end);

        // Set the visible rows in the target component.
        // setValue should exist on formio components; call defensively.
        if (typeof this.targetComponent.setValue === "function") {
            this.targetComponent.setValue(pageSlice);
        } else {
            // fallback: set dataValue directly (less ideal)
            this.targetComponent.dataValue = pageSlice;
        }

        // Update UI text and button states
        this.updateUI();
    }

    /**
     * Update the DOM refs for numbers and button disabled states
     */
    updateUI() {
        // First/last item numbers: show 1 when no items
        const firstNum =
            this.totalRowsNum === 1
                ? 1
                : (this.currentPageNum - 1) * this.pageLimit + 1;
        const lastNum =
            this.totalRowsNum === 1
                ? 1
                : Math.min(this.currentPageNum * this.pageLimit, this.totalRowsNum);

        if (this.refs.firstItemNum) this.refs.firstItemNum.innerText = firstNum;
        if (this.refs.lastItemNum)
            this.refs.lastItemNum.innerText = lastNum > 0 ? lastNum : 1;
        if (this.refs.totalItemsNum)
            this.refs.totalItemsNum.innerText =
                this.totalRowsNum > 0 ? this.totalRowsNum : 1;
        if (this.refs.currentPageNum)
            this.refs.currentPageNum.innerText =
                this.totalRowsNum === 1 ? 1 : this.currentPageNum;
        if (this.refs.totalPagesNum)
            this.refs.totalPagesNum.innerText = this.totalPagesNum;

        // Button enable/disable
        const onFirst = this.totalRowsNum === 1 || this.currentPageNum === 1;
        const onLast =
            this.totalRowsNum === 1 || this.currentPageNum === this.totalPagesNum;

        if (this.refs.firstBtn) this.refs.firstBtn.disabled = onFirst;
        if (this.refs.prevBtn) this.refs.prevBtn.disabled = onFirst;
        if (this.refs.nextBtn) this.refs.nextBtn.disabled = onLast;
        if (this.refs.lastBtn) this.refs.lastBtn.disabled = onLast;
    }

    /**
     * enable/disable all buttons quickly
     */
    setButtonsDisabled(disabled = true) {
        if (this.refs.firstBtn) this.refs.firstBtn.disabled = disabled;
        if (this.refs.prevBtn) this.refs.prevBtn.disabled = disabled;
        if (this.refs.nextBtn) this.refs.nextBtn.disabled = disabled;
        if (this.refs.lastBtn) this.refs.lastBtn.disabled = disabled;
    }

    /**
     * Returns the full dataset (all pages) and the target component key
     * for external use (e.g. on form submit)
     */
    getAllGridRows() {
        return [this.allGridRows, this.targetComponent.key];
    }

    /**
     * Cleanup listeners when component is removed
     */
    detach() {
        // remove button listeners
        if (this.refs.firstBtn && this._firstHandler)
            this.refs.firstBtn.removeEventListener("click", this._firstHandler);
        if (this.refs.prevBtn && this._prevHandler)
            this.refs.prevBtn.removeEventListener("click", this._prevHandler);
        if (this.refs.nextBtn && this._nextHandler)
            this.refs.nextBtn.removeEventListener("click", this._nextHandler);
        if (this.refs.lastBtn && this._lastHandler)
            this.refs.lastBtn.removeEventListener("click", this._lastHandler);

        // remove target change listener
        if (this.targetComponent) {
            if (typeof this.targetComponent.off === "function") {
                if (this._targetChangeHandler)
                    this.targetComponent.off("change", this._targetChangeHandler);
                if (this._targetDeleteHandler)
                    this.targetComponent.off(
                        "dataGridDeleteRow",
                        this._targetDeleteHandler
                    );
            } else if (
                typeof this.targetComponent.removeEventListener === "function"
            ) {
                if (this._targetChangeHandler)
                    this.targetComponent.removeEventListener(
                        "change",
                        this._targetChangeHandler
                    );

                if (this._targetDeleteHandler)
                    this.targetComponent.removeEventListener(
                        "dataGridDeleteRow",
                        this._targetDeleteHandler
                    );
            }
        }

        return super.detach();
    }
}

why do my forEach results change every time the page loads

I want to dynamically create list elements. I used forEach and I console logged the ul but the results aren’t consistent in the console when I reload the page. They are consistent in the UI. But in the console sometimes it shows ”. I can click on it and see the 7 list elements and their ids. Other times it shows ‘ul#genre-list”. I can click on it and it lists info such as an access key, attributes, childNodes, children, etc. I’m not sure what it’s called. But why is it inconsistent?

JS

albums = [
  {
    id: 1,
    genre: 'Rock',
    image1: '/images/album-covers/jimihindrix-areyouexperienced.jpg',
    image2: '/images/album-covers/thedoors.jpg',
  },
  {
    id: 2,
    genre: 'Jazz',
    image1: '/images/album-covers/somethinelse.jpg',
    image2: '/images/album-covers/MilesDavis-BitchesBrew.jpg',
  },
  {
    id: 3,
    genre: 'Hip-Hop',
    image1: '/images/album-covers/mfdoom-mmfood.jpg',
    image2: '/images/album-covers/nas-illmatic.jpg',
  },
  {
    id: 4,
    genre: 'Soul',
    image1: '/images/album-covers/aliciakeys-diary.jpeg',
    image2: '/images/album-covers/ettajames-tellmama.jpg',
  },
  {
    id: 5,
    genre: 'Electronic',
    image1: '/images/album-covers/burial-tunes.jpg',
    image2: '/images/album-covers/björk-homogenic.jpg',
  },
  {
    id: 6,
    genre: 'Classic',
    image1: '/images/album-covers/sparks-kimonomyhouse.jpg',
    image2: '/images/album-covers/chakakhan-rufus.jpg',
  },

  {
    id: 7,
    genre: 'Pop',
    image1: '/images/album-covers/beatles-sgtpeppers.jpg',
    image2: '/images/album-covers/prince-purplerain.png.webp',
  },
];

const genreList = document.getElementById('genre-list');

const handleClick = () => {
  albums.forEach((album) => {
    const content = `<li id=${album.genre}>${album.genre}</li>`;
    genreList.innerHTML += content;
    console.log(genreList);
  });
};

document.addEventListener('DOMContentLoaded', () => {
  handleClick();
});

HTML

<ul id="genre-list"></ul>

Plotly R: Annotations showing fixed X values on hover despite recalculating closest points across subplots

I’m working with a Plotly figure in R that has 3 subplots sharing the same Y-axis (using subplot() with shareY = TRUE). I’ve implemented custom hover behavior using onRender() that:

  1. Draws a horizontal dashed line across all subplots at the cursor’s Y position
  2. For each subplot, finds the closest point to the hovered Y value
  3. Displays an annotation showing the X and Y values of that closest point

The Issue: The Y values in the annotations update correctly as I move the cursor, but the x values don’t change.

What I Want: When hovering over any subplot, I want to see 3 annotations (one per subplot), each showing:

  • The X value of the closest point in that specific subplot
  • The Y value at the cursor position

Both values should update dynamically as the cursor moves.

What I’m Getting:

  • Y values update correctly ✓
  • Annotations move to correct positions ✓
  • X values stay fixed at the initial hover value ✗

Reproducible Example

library(plotly)
library(htmlwidgets)

set.seed(123)
mk_day <- function(n) {
  base <- as.POSIXct(Sys.Date(), tz = "UTC")
  t <- base + sort(sample(0:(24*60*60-1), n))
  data.frame(time = t, value = rnorm(n))
}
df1 <- mk_day(60)
df2 <- transform(mk_day(80), value = value * 2 + 3)
df3 <- transform(mk_day(40), value = value * 3 + 6)

p1 <- plot_ly(df1, x = ~value, y = ~time, type = "scatter", mode = "lines+markers", name = "Serie 1")

p2 <- plot_ly(df2, x = ~value, y = ~time, type = "scatter", mode = "lines+markers", name = "Serie 2")

p3 <- plot_ly(df3, x = ~value, y = ~time, type = "scatter", mode = "lines+markers", name = "Serie 3")

fig <- subplot(p1, p2, p3, nrows = 1, shareY = TRUE, titleX = TRUE, titleY = TRUE) |>
  layout(
    hovermode = "y",
    yaxis = list(type = "date", tickformat = "%H:%M", title = "Hora (24h)"),
    yaxis2 = list(type = "date", tickformat = "%H:%M"),
    yaxis3 = list(type = "date", tickformat = "%H:%M"),
    margin = list(t = 60, r = 10, b = 40, l = 60)
  )


fig_fixed <- onRender(fig, "
function(el, x) {
  var gd = document.getElementById(el.id);

  // Map subplots by X-axis only; Y is shared
  var xAxes = ['x', 'x2', 'x3'];

  // Helper: get x-axis name for a trace (e.g., 'x', 'x2', 'x3')
  function xAxisOfTrace(tr) {
    if (tr && typeof tr.xaxis === 'string') return tr.xaxis; // 'x', 'x2', 'x3'
    return 'x'; // fallback
  }

  gd.on('plotly_hover', function(evt) {
    if (!evt || !evt.points || !evt.points.length) return;

    // 1) Y value under the cursor (shared Y coordinates)
    var yHover = evt.points[0].y;

    // 2) Single horizontal line across ALL subplots (shared Y)
    var lineShape = [{
      type: 'line',
      xref: 'paper', x0: 0, x1: 1,
      yref: 'y',     y0: yHover, y1: yHover,
      line: { width: 2, dash: 'dot' }
    }];

    // 3) For each subplot (x, x2, x3), find the x whose y is closest to yHover
    //    We compute ONE annotation per subplot.
    var bestByXAxis = {}; // e.g., { x: {x:..., y:..., diff:...}, x2: {...}, x3: {...} }

    for (var i = 0; i < gd.data.length; i++) {
      var tr = gd.data[i];
      if (!tr || !tr.x || !tr.y) continue;
      if (!Array.isArray(tr.x) || !Array.isArray(tr.y) || tr.x.length !== tr.y.length) continue;

      var xa = xAxisOfTrace(tr); // 'x' | 'x2' | 'x3'

      // Find nearest y
      var bestIdx = 0, bestDiff = Infinity;
      for (var k = 0; k < tr.y.length; k++) {
        var d = Math.abs(tr.y[k] - yHover);
        if (d < bestDiff) { bestDiff = d; bestIdx = k; }
      }

      var pick = { x: tr.x[bestIdx], y: tr.y[bestIdx], diff: bestDiff };
      if (!bestByXAxis[xa] || pick.diff < bestByXAxis[xa].diff) {
        bestByXAxis[xa] = pick;
      }
    }

    // 4) Build dynamic annotations (always yref: 'y' because Y is shared)
    var dynAnnotations = [];
    xAxes.forEach(function(xa) {
      var pick = bestByXAxis[xa];
      if (!pick) return;

      // If x are dates (POSIXct), text may need formatting on the R side; here we leave raw.
      var txt = 'x = ' + pick.x + '<br>y ≈ ' + yHover;

      dynAnnotations.push({
        xref: xa,     // 'x' | 'x2' | 'x3'
        yref: 'y',    // shared Y axis
        x: pick.x,
        y: yHover,    // lock onto the horizontal guide
        text: txt,
        showarrow: true,
        arrowhead: 2,
        ax: 20, ay: -20,
        bgcolor: 'rgba(255,255,255,0.85)',
        bordercolor: '#333',
        borderwidth: 1,
        font: { size: 12, color: '#111' },
        align: 'left',
        name: xa + '_' + Math.random() // Fuerza actualización

      });
    });

    // 5) Replace shapes & annotations (do NOT merge with any base annotations)
Plotly.relayout(gd, { shapes: lineShape, annotations: [] }).then(function() {
  Plotly.relayout(gd, { annotations: dynAnnotations });
});
  });

  gd.on('plotly_unhover', function() {
    // Clear all dynamic overlays
    Plotly.relayout(gd, { shapes: [], annotations: [] });
  });
}
")


fig_fixed

Mineflayer assistance with block interactions

I am trying to make a Minecraft mineflayer bot that loads ender pearls in pearl stasis chambers by making it interact with a trapdoor at coordinates that are specified in a postgres database. I have tried a lot but it doesnt change the state of the trapdoor. here is my code. Any suggestions?

import mineflayer from 'mineflayer';
import pathfinderPkg from 'mineflayer-pathfinder';
const { pathfinder, Movements, goals } = pathfinderPkg;

import pg from 'pg';
import fetch from 'node-fetch';
import { Vec3 } from 'vec3';
import mcData from 'minecraft-data';

const { Client } = pg;
const { GoalNear } = goals;

const BOT_CONFIG = {
    host: 'localhost',
    port: 25565,
    username: '33_x',
    auth: 'microsoft',
    version: '1.21.4',
    dbConfig: {
        user: 'postgres',
        host: 'localhost',
        database: 'remotepearl',
        password: 'postgres',
        port: 5432,
    },
    tableName: 'accounts',
    columnUUID: 'uuid',
    columnX: 'x',
    columnY: 'y',
    columnZ: 'z',
    columnWorld: 'world',
    TPLookupCommand: '?tp',
    ActivationRetryCount: 3,
    ActivationRetryDelay: 1500,
    TrapdoorSearchRadius: 3,
    AntiAFKSneakInterval: 10000,
    AntiAFKSneakDuration: 500,
};

const taskQueue = [];
let isProcessingTask = false;

function addTask(task) {
    taskQueue.push(task);
    processQueue();
}

async function processQueue() {
    if (isProcessingTask || taskQueue.length === 0) return;
    isProcessingTask = true;
    const task = taskQueue.shift();
    try {
        await task();
    } catch (error) {
        console.error('Task failed:', error);
    } finally {
        isProcessingTask = false;
        processQueue();
    }
}

async function getUuidFromUsername(username) {
    try {
        const response = await fetch(`https://api.mojang.com/users/profiles/minecraft/${username}`);
        if (!response.ok) return null;
        const data = await response.json();
        return data?.id;
    } catch {
        return null;
    }
}

async function retryOperation(func, maxRetries, delayMs) {
    for (let i = 0; i < maxRetries; i++) {
        try {
            return await func();
        } catch (error) {
            if (i < maxRetries - 1) {
                await new Promise(resolve => setTimeout(resolve, delayMs));
            } else {
                throw error;
            }
        }
    }
}

function getNearbyTrapdoor(center, range) {
    for (let dx = -range; dx <= range; dx++) {
        for (let dy = -range; dy <= range; dy++) {
            for (let dz = -range; dz <= range; dz++) {
                const pos = center.offset(dx, dy, dz);
                const block = bot.blockAt(pos);
                if (block && block.name.includes('trapdoor')) return block;
            }
        }
    }
    return null;
}

async function safeActivateBlock(blockToClick, targetName) {
    const targetPoint = blockToClick.position.offset(0.5, 0.5, 0.5);
    for (let i = 0; i < 2; i++) {
        try {
            const dist = bot.entity.position.distanceTo(targetPoint);
            if (dist > 2) {
                await bot.pathfinder.goto(new GoalNear(blockToClick.position.x, blockToClick.position.y, blockToClick.position.z, 1));
            }
            const facePoint = blockToClick.position.offset(0.5, 0.5, 0);
            await bot.lookAt(facePoint, true);
            await bot.look(0, bot.entity.pitch, true);
            await bot.waitForTicks(2);
            bot.setControlState('sneak', true);
            await bot.waitForTicks(2);
            bot.activateItem();
            await bot.waitForTicks(2);
            bot.activateItem();
            await bot.waitForTicks(2);
            bot.setControlState('sneak', false);
            const newBlock = bot.blockAt(blockToClick.position);
            if (newBlock && newBlock.name.includes('trapdoor')) return;
            throw new Error('Trapdoor activation failed');
        } catch (e) {
            if (i < 1) await bot.waitForTicks(10);
            else throw e;
        } finally {
            bot.setControlState('sneak', false);
        }
    }
}

const bot = mineflayer.createBot(BOT_CONFIG);
bot.loadPlugin(pathfinder);

bot.on('spawn', () => {
    const data = mcData(bot.version);
    const defaultMove = new Movements(bot, data);
    bot.pathfinder.setMovements(defaultMove);
    startAntiAFK();
});

bot.on('error', console.error);
bot.on('kicked', console.error);

bot.on('chat', (username, message) => {
    if (username === bot.username) return;
    const args = message.trim().split(' ');
    const command = args[0];
    const targetPlayer = args[1];
    if (command === BOT_CONFIG.TPLookupCommand && targetPlayer) {
        addTask(() => handleTpCommand(username, targetPlayer));
    }
});

function startAntiAFK() {
    setInterval(() => {
        if (!isProcessingTask) {
            bot.setControlState('sneak', true);
            setTimeout(() => bot.setControlState('sneak', false), BOT_CONFIG.AntiAFKSneakDuration);
        }
    }, BOT_CONFIG.AntiAFKSneakInterval);
}

async function handleTpCommand(requesterName, targetName) {
    const dbClient = new Client(BOT_CONFIG.dbConfig);
    try {
        const uuid = await getUuidFromUsername(targetName);
        if (!uuid) return;
        await dbClient.connect();
        const dbResult = await dbClient.query(
            `SELECT "${BOT_CONFIG.columnX}", "${BOT_CONFIG.columnY}", "${BOT_CONFIG.columnZ}", "${BOT_CONFIG.columnWorld}" 
             FROM ${BOT_CONFIG.tableName} 
             WHERE "${BOT_CONFIG.columnUUID}" = $1`,
            [uuid]
        );
        if (dbResult.rows.length === 0) return;
        const { x, y, z, world } = dbResult.rows[0];
        const dbCenterPos = new Vec3(x, y, z);
        const targetDimension = world.toLowerCase().replace('minecraft:', '');
        if (!bot.game.dimension.includes(targetDimension)) return;
        const blockToClick = getNearbyTrapdoor(dbCenterPos, BOT_CONFIG.TrapdoorSearchRadius);
        if (!blockToClick) throw new Error('Trapdoor not found');
        const trapdoorPos = blockToClick.position;
        const botStandPos = trapdoorPos.offset(0, 0, 1);
        const pathfindingGoal = new GoalNear(botStandPos.x, botStandPos.y, botStandPos.z, 0);
        bot.clearControlStates();
        try {
            await bot.pathfinder.goto(pathfindingGoal);
        } catch {
            if (bot.entity.position.distanceTo(botStandPos.offset(0.5, 0.5, 0.5)) > 1.5) throw new Error('Pathfinding failed');
        }
        bot.pathfinder.stop();
        bot.clearControlStates();
        await bot.waitForTicks(2);
        await safeActivateBlock(blockToClick, targetName);
    } catch (error) {
        bot.pathfinder.stop();
        bot.clearControlStates();
        bot.setControlState('sneak', false);
        console.error(error.message);
    } finally {
        if (dbClient) await dbClient.end();
    }
}

I tried changing the way it interacted but nothing works. if it works well it should interact with a specific block and make that block change states, thew block being a trapdoor that it should clode, thus making the ender pearl despawn and teleporting the player.