Bugging at rescale() function in D3js

i’m working on a data visualize project and trying to use D3js library for graphs. Everything is fine, except when I try to let my bar chart zoomable on X scale.

<div class="row" id="bar-chart-append">
              <div class="container" style="margin: 20px; margin-top: 0px">
                <input type="number" id="numofservice" placeholder="Number of service providers" class="col-3" step="10" min="0">
                <select id="select-order" class="col-8">
                  <h6 class="dropdown-item-text">Order</h6>
                  <option value="alphabetical">Alphabetical</option>
                  <option value="ascending">TFT Score, ascending</option>
                  <option value="descending" selected>TFT Score, descending</option>
                </select>
              </div>
            <div id="tooltip2" class="tooltip bs-tooltip-bottom"></div>
          </div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/d3.min.js"></script>
<script src="/js/graph/graphs.js"></script>

graphs.js:

const numOfService = document.getElementById('numofservice');
const barChartAppend = document.getElementById('bar-chart-append');
numOfService.addEventListener('change', async function() {
        const value = numOfService.value;
        if (!isNaN(value) && value.trim() !== '') {
            data2 = await fetch(`/api/topUser?n=${value}`).then(response => response.json());
            barChartAppend.removeChild(barChartSVG);
            barChartSVG = barChart(data2, barChartAppend.clientWidth, barChartAppend.clientHeight);
            barChartAppend.append(barChartSVG);

        } else {
            console.log('The value is not a number:', value);
        }
    });
$(document).ready(function() {
        $('.selectpicker').selectpicker();
        $('#select-order').on('changed.bs.select', function(e, clickedIndex, isSelected, previousValue) {
            console.log('Selected value:', $(this).val());
            switch ($(this).val()) {
                case 'alphabetical':
                    barChartSVG.update((a, b) => a.owner.localeCompare(b.owner));
                    break;
                case 'ascending':
                    barChartSVG.update((a, b) => a.first_combine - b.first_combine);
                    break;
                case 'descending':
                    barChartSVG.update((a, b) => b.first_combine - a.first_combine);
                    break;
            }
        });
    });
window.onload = async function() {
    var data2 = await fetch('/api/topUser?n=10').then(response => response.json());
    var barChartSVG = barChart(data2, barChartAppend.clientWidth, barChartAppend.clientHeight);
    barChartAppend.append(barChartSVG);
}
function barChart(data2, parentWidth = 1200, parentHeight = 400) {
    // Specify the chart’s dimensions.
    const width = parentWidth;
    const height = Math.min(parentHeight, width / 3);
    const marginTop = 20;
    const marginRight = 0;
    const marginBottom = 30;
    const marginLeft = 40;
    const barColor = "#ff8c00";

    // Declare the x (horizontal position) scale and the corresponding axis generator.
    const x = d3.scaleBand()
        .domain(data2.map(d => d.owner))
        .range([marginLeft, width - marginRight])
        .padding(0.1);

    const xAxis = d3.axisBottom(x).tickSizeOuter(0);

    // Declare the y (vertical position) scale.
    const y = d3.scaleLinear()
        .domain([0, d3.max(data2, d => d.first_combine)]).nice()
        .range([height - marginBottom, marginTop]);

    // Create the SVG container.
    const svg = d3.create("svg")
        .attr("viewBox", [0, 0, width, height])
        .attr("style", `max-width: ${width}px; height: auto; font: 10px rubik; overflow: visible;`)
        .attr("width", width)
        .attr("height", height);

    const barsGroup = svg.append("g").attr("class", "bars");

    const bar = barsGroup.selectAll("rect")
        .data(data2)
        .join("rect")
        .attr("fill", barColor) // Default color of the bars.
        .attr("x", d => x(d.owner))
        .attr("y", d => y(d.first_combine))
        .attr("height", d => y(0) - y(d.first_combine))
        .attr("width", x.bandwidth())
        .on("mouseover", function(event, d) {
            d3.select('#tooltip2').html(nodeDetail(d)).style("visibility", "visible").style("opacity", 1);
            d3.select(this)
                .attr("fill", shadeColor(barColor, -15));
        })
        .on("click", function(event, d) {
            window.open(`/profile?owner=${d.owner}`, '_blank');
        })
        .on("mousemove", function(event, d) {
            d3.select('#tooltip2')
                .style("top", (event.pageY - 10) + "px")
                .style("left", (event.pageX + 10) + "px");
        })
        .on("mouseout", function() {
            d3.select('#tooltip2').html(``).style("visibility", "hidden").style("opacity", 0);
            d3.select(this).attr("fill", barColor);
        });

    // Create the axes.
    const gx = svg.append("g")
        .attr("class", "x-axis")
        .attr("transform", `translate(0,${height - marginBottom})`)
        .call(xAxis);

    const gy = svg.append("g")
        .attr("class", "y-axis")
        .attr("transform", `translate(${marginLeft},0)`)
        .call(d3.axisLeft(y).tickFormat(y => y))
        .call(g => g.append("text")
            .attr("x", -marginLeft)
            .attr("y", 0)
            .attr("fill", "currentColor")
            .attr("text-anchor", "start")
            .text("↑ TFT Score"))
        .call(g => g.select(".domain").remove());

     function zoomed(event) {
        console.log('Zoom event:', event);
        console.log('Transform:', event.transform);
        console.log('X scale:', x);
        const transform = event.transform;
        const newX = transform.rescaleX(x);
        console.log('New X scale:', newX);
        gx.call(d3.axisBottom(newX).tickSizeOuter(0));
        barsGroup.selectAll("rect")
            .attr("x", d => newX(d.owner))
            .attr("width", newX.bandwidth());
    }

    svg.call(d3.zoom()
        .scaleExtent([1, 8])
        .translateExtent([[0, 0], [width, height]])
        .extent([[0, 0], [width, height]])
        .on("zoom", zoomed));

    // Return the chart, with an update function that takes as input a domain
    // comparator and transitions the x axis and bar positions accordingly.
    return Object.assign(svg.node(), {
        update(order) {
            x.domain(data2.sort(order).map(d => d.owner));

            const t = svg.transition()
                .duration(750);

            bar.data(data2, d => d.owner)
                .order()
                .transition(t)
                .delay((d, i) => i * 20)
                .attr("x", d => x(d.owner));

            gx.transition(t)
                .call(xAxis)
                .selectAll(".tick")
                .delay((d, i) => i * 20);
        }
    });
}

The data2 will be an array of json objects like [{"owner" : "Mei","id" : "1234","group" : ["service_provider"],"first_combine":100,"properties" : {}}]

Everytime I try to call the zoomed() function, it throws an exception:

Uncaught TypeError: undefined is not a function
    at Array.map (<anonymous>)
    at rescaleX (graphs.js:476:28)
    at SVGSVGElement.zoomed (graphs.js:481:22)
    at Dt.call (d3.min.js:2:15713)
    at M.emit (d3.min.js:2:278459)
    at M.zoom (d3.min.js:2:278301)
    at SVGSVGElement.T (d3.min.js:2:274295)
    at SVGSVGElement.<anonymous> (d3.min.js:2:20686)

These console.log() line will return:

Zoom event: xw {type: 'zoom', sourceEvent: WheelEvent, transform: ww, _: Dt, target: ƒ}
Transform: ww {k: 1.9042067625774186, x: -233.285344744974, y: -176.10556683706443}
X scale: ƒ i(i){let o=t.get(i);if(void 0===o){if(r!==pg)return r;t.set(i,o=n.push(i)-1)}return e[o%e.length]}

I think X scale is bugging but I don’t know how to fix that. Is there anyone can help me with that problem?