React router dom 6.22 multiple level nested children routes index page not rendering

I have multiple nested routes in, however the index route component that is 2 levels deep is not rendering and just showing a blank page.

// I cannot add an `index` property because you can't have child routes if it is an index route.


export const routes= [
  { 
    // Put a navigate element since index routes cannot have children. 
    // If this navigate is removed, it cannot reroute using index.
    element: () => <Navigate to={`one`} />,
    path: '/',
    name: 'default',
    children: [
      {
        // Once it is navigated to here from the default `/` route, it just renders a blank page and not the component `NestedComponentOne`
        element: NestedComponentOne,
        path: 'one',
        name: 'One',
        children: [
          {
            element: DeeplyNestedComponentOne,
            name: 'Deep One',
            path: 'deep-one',
          },
          {
            element: DeeplyNestedComponentTwo,
            name: 'Deep Two',
            path: 'deep-two',
          },
        ]
      },
    ]
  }
]


const MyComponent= () => {
  return (
    <>
      <div style={{ margin: "0px 0px" }}>
        <Routes>
          {routes.map((route, idx) => {
            if (route.children && route.children.length > 0) {
              return (
                <Route
                  key={`child-routes-auth-${idx}`}
                  element={route?.element && <route.element />}
                  errorElement={route?.errorElement}
                  name={route.name}
                  path={route.path}
                >
                  {route.children.map((childRoute, childIdx) => {
                    if (childRoute.children && childRoute.children.length > 0) {
                      return (
                        <Route
                          key={`inner-child-auth-routes-${childIdx}`}
                          element={childRoute?.element && <childRoute.element />}
                          errorElement={childRoute?.errorElement}
                          name={childRoute.name}
                          path={childRoute.path}
                        >
                          {childRoute.children.map((innerRoutes, innerIndex) => {
                            return (
                              innerRoutes.element && (
                                <Route
                                  key={`nested-inner-auth-${innerIndex}`}
                                  element={innerRoutes?.element && <innerRoutes.element />}
                                  errorElement={innerRoutes?.errorElement}
                                  index={innerRoutes?.index}
                                  name={innerRoutes.name}
                                  path={innerRoutes.path}
                                />
                              )
                            )
                          })}
                        </Route>
                      )
                    }
                    return (
                      childRoute.element && (
                        <Route
                          key={`childIdx-auth-${childIdx}`}
                          element={childRoute?.element && <childRoute.element />}
                          errorElement={childRoute?.errorElement}
                          index={childRoute?.index}
                          name={childRoute.name}
                          path={childRoute.path}
                        />
                      )
                    )
                  })}
                </Route>
              )
            }
            return (
              route.element && (
                <Route
                  key={`top-routes-${idx}`}
                  element={<route.element />}
                  errorElement={route?.errorElement}
                  index={route?.index}
                  path={route.path}
                  name={route.name}
                />
              )
            )
          })}
        </Routes>
      </div>
    </>
  );
}

How to have eCharts tooltip fully visible in the page with Bootstrap

I was trying to implement a Bootstrap 5.x design for some eCharts graphs.

But the tooltip goes out of the page and only part of it is visible.

The code it’s too long to put in stackoverflow snippet so I made a Jsfiddle as example.

See this:

https://jsfiddle.net/18g0op7c/

the chart it’s included in a div tag like this:

<div id="A" style="width: 100%; height: 100px; background-color: rgb(102, 102, 102);">
  <div id="mainchart" style="width: 100%; height: 100%;">
    
  </div>
</div>

So the question it’s:

How to have eCharts tooltip fully visible in the page with Bootstrap?

Adding and removing selections from an array for a compensation calculator

codepen: https://codepen.io/strozilla/pen/abVYbrx

const compensationRates = {
    10: { single: 171.23 },
    20: { single: 338.49 },
    30: {
        single: 524.31,
        withSpouse: 586.31,
        withSpousewithoneParent: 636.31,
        withSpousewithTwoParents: 686.31,
        singlewithOneParent: 574.31,
        singlewithTwoParents: 624.331,
        singlewithOneChild: 565.31,
        withSpousewithOneChild: 632.21,
        withSpousewithOneParentwithOneChild: 682.31,
        withSpousewithTwoParentswithOneChild: 732.31,
        singlewithOneParentwithOneChild: 615.31,
        sinlgewithTwoParentswithOneChild: 665.31,
        additionalChildUnder18: 31.0,
        additionalChildOver18: 100.0,
        aidAndAttendance: 57.0
    },
    40: {
        single: 755.28,
        withSpouse: 838.28,
        withSpousewithOneParent: 904.28,
        withSpousewithTwoParents: 970.28,
        withOneParent: 821.28,
        withTwoParents: 887.28,
        withOneChild: 810.28,
        withSpousewithOneChild: 899.28,
        withSpousewithOneParentwithOneChild: 965.28,
        withSpousewithTwoParentswithOneChild: 1031.28,
        withOneParentwithOneChild: 876.28,
        withTwoParentswithOneChild: 942.28,
        additionalChildUnder18: 41.0,
        additionalChildOver18: 133.0,
        aidAndAttendance: 76.0
    },
    50: {
        single: 1075.16,
        withSpouse: 1179.16,
        withSpousewithOneParent: 1262.16,
        withSpousewithTwoParents: 1345.16,
        withOneParent: 1158.16,
        withTwoParents: 1144.16,
        withOneChild: 1241.16,
        withSpousewithOneChild: 1255.16,
        withSpousewithOneParentwithOneChild: 1338.16,
        withSpousewithTwoParentswithOneChild: 1421.16,
        withOneParentwithOneChild: 1227.16,
        withTwoParentswithOneChild: 1310.16,
        additionalChildUnder18: 51.0,
        additionalChildOver18: 167.0,
        aidAndAttendance: 95.0
    },
    60: {
        single: 1361.88,
        withSpouse: 1486.88,
        withSpousewithOneParent: 1586.88,
        withSpousewithTwoParents: 1686.88,
        withOneParent: 1461.88,
        withTwoParents: 1561.88,
        withOneChild: 1444.88,
        withSpousewithOneChild: 1577.88,
        withSpousewithOneParentwithOneChild: 1677.88,
        withSpousewithTwoParentswithOneChild: 1777.88,
        withOneParentwithOneChild: 1544.88,
        withTwoParentswithOneChild: 1644.88,
        additionalChildUnder18: 62.0,
        additionalChildOver18: 200.0,
        aidAndAttendance: 114.0
    },
    70: {
        single: 1716.28,
        withSpouse: 1861.28,
        withSpousewithOneParent: 1978.28,
        withSpousewithTwoParents: 2095.28,
        singlewithOneParent: 1833.28,
        singlewithTwoParents: 1950.28,
        singlewithOneChild: 1813.28,
        withSpousewithOneChild: 1968.28,
        withSpousewithOneParentwithOneChild: 2085.28,
        withSpousewithTwoParentswithOneChild: 2202.28,
        singlewithOneParentwithOneChild: 1930.28,
        singlewithTwoParentswithOneChild: 2047.28,
        additionalChildUnder18: 72.0,
        additionalChildOver18: 234.0,
        aidAndAttendance: 134.0
    },
    80: {
        single: 1995.01,
        withSpouse: 2161.01,
        withSpousewithOneParent: 2294.01,
        withSpousewithTwoParents: 2427.01,
        singlewithOneParent: 2128.01,
        singlewithTwoParents: 2261.01,
        singleithOneChild: 2106.01,
        withSpousewithOneChild: 2283.01,
        withSpousewithOneParentwithOneChild: 2416.01,
        withSpousewithTwoParentswithOneChild: 2549.01,
        singlewithOneParentwithOneChild: 2239.01,
        singlewithTwoParentswithOneChild: 2372.01,
        additionalChildUnder18: 82.0,
        additionalChildOver18: 267.0,
        aidAndAttendance: 153.0
    },
    90: {
        single: 2241.91,
        withSpouse: 2428.91,
        withSpousewithOneParent: 2578.91,
        withSpousewithTwoParents: 2728.91,
        singlewithOneParent: 2391.91,
        singlewithTwoParents: 2541.91,
        singlewithOneChild: 2366.91,
        withSpousewithOneChild: 2565.91,
        withSpousewithOneParentwithOneChild: 2715.91,
        withSpousewithTwoParentswithOneChild: 2865.91,
        singlewithOneParentwithOneChild: 2516.91,
        singlewithTwoParentswithOneChild: 2666.91,
        additionalChildUnder18: 93.0,
        additionalChildOver18: 301.0,
        aidAndAttendance: 172.0
    },
    100: {
        single: 3737.85,
        withSpouse: 3946.25,
        withSpousewithOneParent: 4113.51,
        withSpousewithTwoParents: 4280.77,
        singlewithOneParent: 3905.11,
        singlewithTwoParents: 4072.37,
        singlewithOneChild: 3877.22,
        withSpousewithOneChild: 4098.87,
        withSpousewithoneParentwithOneChild: 4266.13,
        withSpousewithTwoParentswithOneChild: 4433.39,
        singlewithOneParentwithOneChild: 4044.48,
        singlewithTwoParentswithOneChild: 4211.74,
        additionalChildUnder18: 1033.55,
        additionalChildOver18: 334.49,
        aidAndAttendance: 191.14
    }
}

let limb = []
let disabilities = []
let bilateralDisabilities = []
let selectedOptions = []
let selectionsDisplay
let compensation
let totalCompensation = 0
let combinedPercentage = 0
let selectedBodyPart = null
let resultSpan = document.getElementById('result')

function roundToNearest10(value) {
    return Math.round(value / 10) * 10
}

function calculateCompensation() {
    document.querySelectorAll('.body-part').forEach(function (bodyPart) {
        bodyPart.addEventListener('click', function () {
            selectedBodyPart = bodyPart.getAttribute('data-body-limb')
        })
    })

    document.querySelectorAll('.percentage').forEach(function (button) {
        button.addEventListener('click', function () {
            let value = parseInt(button.value)
            let selectionText = ''

            if (selectedBodyPart) {
                selectionText = `${selectedBodyPart} ${value}%`
                limb.push(selectedBodyPart) // Add to the limb array

                // Check if there are already limbs with the same data-body-part
                const matchingLimb = limb.filter((l) => l === selectedBodyPart)
                console.log(matchingLimb + ' matching limbs')

                // If there's more than one of the same body part, it's bilateral
                if (matchingLimb.length > 1) {
                    bilateralDisabilities = bilateralDisabilities.concat(disabilities)
                    disabilities.length = 0
                    bilateralDisabilities.push(value)
                } else {
                    disabilities.push(value)
                }

                selectedBodyPart = null // Reset the selected body part after it's used
            } else {
                if (bilateralDisabilities.length > 1) {
                    selectionText = `${value}%`
                    bilateralDisabilities.push(value)
                } else {
                    selectionText = `${value}%`
                    disabilities.push(value)
                }
            }
            console.log(value)
            console.log(disabilities + ' disabilities')
            console.log(bilateralDisabilities + ' bilateral disabilities')

            console.log(limb + ' limb')

            addSelectionBox(selectionText)

            console.log(bilateralDisabilities + ' bilateral 1')
            button.classList.remove('selected')
            updateTotalCompensation()
        })
    })

    document.querySelectorAll('.optional').forEach(function (element) {
        element.addEventListener('change', function () {
            updateTotalCompensation()
        })
    })
    compensation.innerHTML = '$' + totalCompensation.toFixed(2)
    resultSpan.innerHTML = combinedPercentage + '%'

    updateTotalCompensation()
}

function updateTotalCompensation() {
    compensation = document.getElementById('compensation')

    selectionsDisplay = document.getElementById('selectionsDisplay')
    if (selectionsDisplay.childNodes.length === 0) {
        combinedPercentage = 0
        totalCompensation = 0
        document.getElementById('result').innerHTML = '0%'
        document.getElementById('compensation').innerHTML = '$0.00'
        return
    }

    if (disabilities.length > 0) {
        combinedPercentage =
            disabilities.reduce(function (acc, cur) {
                return acc * (1 - cur / 100)
            }, 1) * 100
        combinedPercentage = 100 - combinedPercentage
        combinedPercentage = roundToNearest10(combinedPercentage)

        totalCompensation = compensationRates[combinedPercentage]['single']
    }

    if (bilateralDisabilities.length > 0) {
        var bilateralCombined =
            bilateralDisabilities.reduce(function (acc, cur) {
                return acc * (1 - cur / 100)
            }, 1) * 100
        bilateralCombined = 100 - bilateralCombined + 10
        bilateralCombined = roundToNearest10(bilateralCombined)

        console.log(bilateralCombined + ' bilateral combined')

        totalCompensation = compensationRates[bilateralCombined]['single']
        combinedPercentage = bilateralCombined
    }

    compensation.innerHTML = '$' + totalCompensation.toFixed(2)
    document.getElementById('result').innerHTML = combinedPercentage + '%'

    console.log(disabilities + ' disabilities')
    console.log(bilateralCombined + ' bilateral combined')
    console.log(combinedPercentage + ' bilateral 3')
    console.log(totalCompensation + ' bilateral 4')

    selectedOptions = []
    if (selectedOptions.length > 0) {
        document.querySelectorAll('.optional:checked').forEach(function (optional) {
            if (optional.id !== 'none') {
                selectedOptions.push(optional.id)
            }
            console.log(selectedOptions + ' first selected options')
        })

        totalCompensation =
            compensationRates[combinedPercentage][selectedOptions.join('')]
        compensation.innerHTML = '$' + totalCompensation.toFixed(2)
        document.getElementById('result').innerHTML = combinedPercentage + '%'
        console.log(combinedPercentage + ' combined percentage after bilateral')
    }
    // Watch dropdowns for changes
    var childrenUnder18 = parseInt(
        document.getElementById('childrenUnder18').value
    )
    var childrenOver18 = parseInt(document.getElementById('childrenOver18').value)

    // Update selectedOptions array
    if (childrenUnder18 > 0) {
        if (!selectedOptions.includes('withOneChild')) {
            selectedOptions.push('withOneChild')
            totalCompensation =
                compensationRates[combinedPercentage][selectedOptions.join('')]
            console.log(selectedOptions + ' inside under 18')
            console.log(totalCompensation + ' with one child')
        }

        if (childrenUnder18 > 1 && childrenOver18 === 0) {
            let addChildUnder18 = childrenUnder18 - 1
            console.log(addChildUnder18)
            if (addChildUnder18 > 0) {
                totalCompensation +=
                    addChildUnder18 *
                    compensationRates[combinedPercentage]['additionalChildUnder18']
                console.log(totalCompensation + ' with addtnl Child')
            }
        } else if (childrenOver18 > 1 && childrenUnder18 > 0) {
            totalCompensation +=
                childrenUnder18 *
                compensationRates[combinedPercentage]['additionalChildUnder18']
            console.log(totalCompensation + ' with addtnl Child')
        } else {
            totalCompensation =
                compensationRates[combinedPercentage][selectedOptions.join('')]
        }
    } else {
        selectedOptions = selectedOptions.filter(
            (option) => option !== 'withOneChild'
        )
    }

    if (childrenOver18 > 0) {
        if (!selectedOptions.includes('withOneChild')) {
            selectedOptions.push('withOneChild')
        }

        if (childrenOver18 > 1 && childrenUnder18 === 0) {
            let addChildOver18 = childrenOver18 - 1
            if (addChildOver18 > 0) {
                totalCompensation +=
                    addChildOver18 *
                    compensationRates[combinedPercentage]['additionalChildOver18']
            }
        } else if (childrenUnder18 > 1 && childrenOver18 > 0) {
            totalCompensation +=
                childrenOver18 *
                compensationRates[combinedPercentage]['additionalChildOver18']
        } else {
            totalCompensation = compensationRates[combinedPercentage]['withOneChild']
        }
    } else {
        selectedOptions = selectedOptions.filter(
            (option) => option !== 'withOneChild'
        )
    }

    console.log(selectedOptions + ' last options')
    console.log(totalCompensation + ' total compensation')
    // Update total compensation display

    compensation.innerHTML = '$' + totalCompensation.toFixed(2)
    document.getElementById('result').innerHTML = combinedPercentage + '%'
}

document
    .getElementById('childrenUnder18')
    .addEventListener('change', updateTotalCompensation)
document
    .getElementById('childrenOver18')
    .addEventListener('change', updateTotalCompensation)

function addSelectionBox(text) {
    selectionsDisplay = document.getElementById('selectionsDisplay')
    let box = document.createElement('div')
    box.className = 'selection-box'
    box.innerHTML = `${text} <span class="remove-box">X</span>`
    selectionsDisplay.appendChild(box)

    box.querySelector('.remove-box').addEventListener('click', function () {
        removeSelection(text, box)
    })
}

function removeSelection(text, box) {
    let value

    if (text.endsWith('%')) {
        value = parseInt(text)

        // Remove from disabilities
        let index = disabilities.indexOf(value)
        if (index !== -1) {
            disabilities.splice(index, 1)
        }

        // Remove from bilateralDisabilities
        index = bilateralDisabilities.indexOf(value)
        if (index !== -1) {
            bilateralDisabilities.splice(index, 1)
        }
    } else {
        // Remove limb selection
        const limbToRemove = text
        const limbIndex = limb.indexOf(limbToRemove)
        if (limbIndex !== -1) {
            limb.splice(limbIndex, 1)
        }
    }

    console.log('Updated disabilities:', disabilities)
    console.log('Updated bilateral disabilities:', bilateralDisabilities)

    box.remove()

    // Determine if we need to switch back from bilateral to disabilities
    if (limb.length > 1) {
        // Check if any limb selections are still present
        const allLimbSelections = limb.filter((l) => l === selectedBodyPart)
        if (allLimbSelections.length <= 1) {
            // Reassign bilateralDisabilities to disabilities if only one or none
            disabilities = disabilities.concat(bilateralDisabilities)
            bilateralDisabilities.length = 0 // Clear bilateralDisabilities array
        }
    }

    // Recalculate combined percentage and total compensation
    updateTotalCompensation()
}

function clearTotals() {
    document
        .querySelectorAll('input[type="checkbox"]')
        .forEach(function (checkbox) {
            checkbox.checked = false
            let label = checkbox.closest('label')
            if (label) {
                label.classList.remove('checked')
            }
        })
    document.getElementById('childrenUnder18').value = '0'
    document.getElementById('childrenOver18').value = '0'
    limb = []
    disabilities = []
    bilateralDisabilities = []
    selectedOptions = []
    totalCompensation = 0
    combinedPercentage = 0

    var selectionsDisplay = document.getElementById('selectionsDisplay')
    selectionsDisplay.innerHTML = ''

    compensation = document.getElementById('compensation')
    compensation.innerHTML = '$' + 0.0
    document.getElementById('result').innerHTML = 0 + '%'

    updateTotalCompensation()
}

document.addEventListener('DOMContentLoaded', (event) => {
    function handleCheckboxChange(event) {
        const group = event.target.closest('div')
        const checkboxes = group.querySelectorAll('.optional')

        checkboxes.forEach((checkbox) => {
            if (checkbox !== event.target) {
                checkbox.checked = false
                const otherLabel = checkbox.closest('label')
                otherLabel.classList.remove('checked')
            }
        })

        let label = event.target.closest('label')
        if (event.target.checked) {
            label.classList.add('checked')
        } else {
            label.classList.remove('checked')
        }

        updateTotalCompensation()
        console.log(totalCompensation)
    }

    document.querySelectorAll('.optional').forEach((checkbox) => {
        checkbox.addEventListener('change', handleCheckboxChange)
    })
})

calculateCompensation()

<div class="calculator">
    <h2>Veteran Disability Calculator</h2>
    <div class="instructions"><span>Enter your disabilities using the buttons below.</span>
    <span>If your disability is on an extremity push that proper leg or arm button then push the percentage</span></div>
    

<div class="body-part-sec">
    <div class="top-left">
        <button class="body-part arm" type="button" data-body-limb="arm">Left Arm</button>
    </div>
    <div class="top-right">
        <button class="body-part arm" type="button" data-body-limb="arm">Right Arm</button>
    </div>
    <div class="bottom-left">
        <button class="body-part leg" type="button" data-body-limb="leg">Left Leg</button>
    </div>
    <div class="bottom-right">
        <button class="body-part leg" type="button" data-body-limb="leg">Right Leg</button>
    </div>
</div>

<div>
 <div class="selections">
            <button class="percentage" value="10">10%</button>
            <button class="percentage" value="20">20%</button>
            <button class="percentage" value="30">30%</button>
            <button class="percentage" value="40">40%</button>
            <button class="percentage" value="50">50%</button>
            <button class="percentage" value="60">60%</button>
            <button class="percentage" value="70">70%</button>
            <button class="percentage" value="80">80%</button>
            <button class="percentage" value="90">90%</button>
            <button class="percentage" value="100">100%</button>
        </div>
</div>
<div id="selectionsDisplay" class="selections-display"></div>

    <div class="options-sec">
        <div class="marital-status">
            <div>What is Your Marital Status?</div>
            <label class="checked"><input class="optional" type="checkbox" id="single">Single</label>
            <label><input class="optional" type="checkbox" id="withSpouse">Married</label>
        </div>
        <div class="dependent-parents">
            <div>Do You Have Any Dependent Parents?</div>
            <label class="checked"><input class="optional" type="checkbox" id="none">None</label>
            <label><input class="optional" type="checkbox" id="withOneParent">One Parent</label>
            <label><input class="optional" type="checkbox" id="withTwoParents">Two Parents</label>
        </div>
    </div>

  <div class="dependent-children-container">
    <div class="dependent-children">
        <label for="childrenUnder18">Dependent Children Under 18: </label>
        <select class="dependent-dropdown" id="childrenUnder18">
            <option id="0" value="0">0</option>
            <option id="1" value="1">1</option>
            <option id="2" value="2">2</option>
            <option id="3" value="3">3</option>
            <option id="4" value="4">4</option>
            <option id="5" value="5">5</option>
            <option id="6" value="6">6</option>
            <option id="7" value="7">7</option>
            <option id="8" value="8">8</option>
            <option id="9" value="9">9</option>
            <option id="10" value="10">10</option>
            </select>
        </div>
        <div class="dependent-children">
            <label for="childrenOver18">Dependent Children Over 18:</label>
            <select class="dependent-dropdown" id="childrenOver18">
                <option id="11" value="0">0</option>
                <option id="12" value="1">1</option>
                <option id="13" value="2">2</option>
                <option id="14" value="3">3</option>
                <option id="15" value="4">4</option>
                <option id="16" value="5">5</option>
                <option id="17" value="6">6</option>
                <option id="18" value="7">7</option>
                <option id="19" value="8">8</option>
                <option id="20" value="9">9</option>
                <option id="21" value="10">10</option>
            </select>
        </div>
    </div>

  <div class="estimated-total">
    <div class="percent-dollar">
        <div class="totals">Combined Disability: <span id="result">0%</span></div>
        <div class="totals">Estimated Monthly Compensation: <span id="compensation">$0.00</span></div>
    </div>
    <button id="clearSelections" class="clear-btn" onclick="clearTotals()">Clear Selections</button>
  </div>
</div>

I have a calculator that is supposed to give an estimated disability compensation. The calculation part is fairly straight forward, there is one calculation for just disabilities, then if you select two arms or two legs, the calculation is different.

When adding selections I seem to be getting the correct calculations, but the issue happens when I try to remove a selection. It should remove the percentage from the array and recalculate. This works if I remove a selection that is just a percentage, but if it is a limb + percentage, it does not recalculate correctly. Looking at the console, the removeSelection function is not removing those percentages from the array, which is weird because they’re only numbers in the array. So not sure why one gets removed but the other doesn’t.
Also, if you have advice on a simpler way to do this, that would be greatly appreciated. Thanks!

I was wondering if this JavaScript piece of code is ok

I’m new to JavaScript and I’m having trouble doing this question and I was wondering if this can work. This is the task.

Write a function toIPv4, which allows the caller to pass 4 String
values and returns a valid IP Address as a String. In your solution,
you must do the following:

  1. Use either arguments or a Rest Parameter to accept multiple values to your function
  2. Make sure the caller passes exactly 4 parameters, error if not
  3. Make sure all 4 values are Strings, error if not
  4. Convert each string value to a number (Integer) and make sure it is in the range 0-255, error if not
  5. If all of the above checks pass, use a Template Literal to return the IP Address as a String
  6. Use the functions from questions 1 and 2 to help you solve 1-5 above For example, toIPv4(“192”, “127”, “50”, “1”) should return
    “192.127.50.1”
function toIPv4(...args) {
  // Check if exactly 4 arguments are passed
  if (args.length !== 4) {
    throw new Error('You must pass exactly 4 parameters.');
  }

  // Check if all arguments are strings and are valid numbers in the range 0-255
  const numbers = args.map(arg => {
    if (typeof arg !== 'string') {
      throw new Error('All arguments must be strings.');
    }
    const num = parseInt(arg, 10); // Convert the string to a number (integer)
    if (isNaN(num) || num < 0 || num > 255) {
      throw new Error('Each string must represent a valid number between 0 and 255.');
    }
    return num;
  });

  // Use Template Literal to return the IP Address as a String
  return `${numbers[0]}.${numbers[1]}.${numbers[2]}.${numbers[3]}`;
}

I’m trying to put the example as the input and it doesn’t work

Issue with CORS when hitting API using LangChain.js with MERN stack [duplicate]


I am using LangChain.js in my MERN stack project and I am importing the following:

import { ChatGoogleGenerativeAI } from "@langchain/google-genai";

Scenario:

  • In my frontend, I am hitting an API endpoint /llm/response which is supposed to interact with Google AI via LangChain.

  • The issue I am facing is that from the frontend I get a CORS error, something like:

    Access to XMLHttpRequest at ‘http://localhost:3000/api/llm/response’ from origin ‘http://localhost:5173’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. `.

  • However, when I test the same API endpoint separately using Postman, it works fine and gives me a response.

Additional observations:

  • When I directly interact with Google AI via LangChain.js from the frontend, it works without any CORS issue, but my API key gets exposed, which is a security risk.

  • I created another endpoint in the backend called /test to check CORS from the frontend through this endpoint, and it gives no error and works fine. So, I don’t think this is a typical CORS error.

Question:

How can I resolve this CORS issue, or what am I missing here?

What I tried and what I was expecting:

  • I tried hitting the /llm/response endpoint from my frontend expecting it to work just like it does in Postman without CORS issues, but instead, I got a CORS error.
  • I also tried setting up a backend proxy to resolve the issue, but it didn’t work. I expected that hitting the API from the frontend would securely interact with the API without exposing my API key.

Get referral code from telegram bot start parameter with JavaScript landing page, and send to Laravel backend

I am making a telegram miniapp, it have options for users to refere others to the app and get reward,
I have completed the authentication and many functions/logics of the app. But extracting the referral code from the ref link eg: https://t.me/my_bot?start=RefC0d3, I have tried a lot of things that did not work

Please can someone help me out, Im stcucked here.
Thanks.

My js code is below:

const telegramWebApp = await loadTelegramSdk();
                if (telegramWebApp) {
                    const { id, first_name, username, start_param } = telegramWebApp.initDataUnsafe;
                    console.log('Telegram User Info:', { id, first_name, username, start_param });
    
                    const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
    
                    const headers = {
                        'Content-Type': 'application/json',
                    };
    
                    if (csrfToken) {
                        headers['X-CSRF-TOKEN'] = csrfToken;
                    }
                    
                    const requestBody = {
                        ...telegramWebApp.initDataUnsafe,
                        referral_code: start_param // Add referral_code to the request body
                    };
    
                    const response = await fetch("{{ route('tg.authenticate') }}", {
                        method: 'POST',
                        headers: headers,
                        body: JSON.stringify(requestBody) // Send referral_code in the request body
                    });
    
                    const data = await response.json();
                    if (data.message === 'Logged in successfully' || data.message === 'User created and logged in') {
                        console.log(`Welcome ${first_name || username}!`);
                        setTimeout(() => {
                            window.location.href = '{{ route('tg.dashboard') }}'; // Redirect after 1.5 seconds
                        }, 1500);
                    } else {
                        console.error('Authentication failed:', data.message);
                    }
                }

In my controller I used Log::info('Request Input:', $request->all()); to check the inputs but the javasacipt is not sending the refferral code.

How to dynamically retrieve the content text of a HTML tag and its child tags?

I would like to know how to dynamically retrieve the content text of a HTML tag and its child tags?

Here is my HTML code, for example:

<p><code>C:<select>
        <option value="test1">test1</option>
        <option value="test2">test2</option>
    </select>test3<select>
        <option value="test4">test4</option>
        <option value="test5">test5</option>
    </select>test6<select>
        <option value="test7">test7</option>
        <option value="test8">test8</option>
        <option value="test9">test9</option>
    </select>test10.txt</code></p>

I would like to create a button after this code, and when it is clicked, I would like to write the content directly within the console.

For example:

C:test2test3test4test6test8test10.txt

or

C:test1test3test5test6test9test10.txt

It might be possible that another paragraph of code only contains 1 or 2 <select> tags. So, I don’t want a code that only works for 3 <select> tags, like in the previous example.

Thank you very much in advance

Discord.js fs.writeFile not updating the correct json

I am using discord.js to write a bot. I am using a json called data in order to hold information that can be changed via slash commands. However, using fs.writeFile doesn’t modify the targeted json.

My file structure is

node_modules
src
 - index.js
 - data.json
.env
package.lock
package.json

This is what data.json looks like when the project is started

{
    "something": "fdafda"
}

This is what index.js looks like:

require('dotenv').config();
const { Client, IntentsBitField } = require('discord.js');

const fs = require('fs');
const dataFileName = './data.json';
const data = require(dataFileName);


const client = new Client({
  intents: [
    IntentsBitField.Flags.Guilds,
    IntentsBitField.Flags.GuildMembers,
    IntentsBitField.Flags.GuildMessages,
    IntentsBitField.Flags.MessageContent,
  ],
});

client.on('ready', (c) => {
  console.log(`✅ ${c.user.tag} is online.`);

  console.log(data);
  data.modCreationId = "new value";

  fs.writeFile(dataFileName, JSON.stringify(data, null, 2), (err) => {
    if (err) return console.log(err);
    console.log(JSON.stringify(data, null, 2));
  });


});

client.login(process.env.DISCORD_TOKEN);

This what’s logged in the terminal when the bot is initialized:

KTANE FAQ#1840 is online.
{ something: 'fdafda' }
{
  "something": "fdafda",
  "modCreationId": "new value"
}

The file is being read correctly as something is populated in the data variable, and the JSON.stringify console.log shows what I want data.json to have, but the file still only shows

{
    "something": "fdafda"
}

When I looked back at my file structure, I realized that a new data.json file was created outside of the src folder. With the correct information.

node_modules
src
 - index.js
 - data.json
 
data.json
.env
package.lock
package.json

I thought getting rid of the json inside the src folder would fix the problem, but a MODULE_NOT_FOUND error appears if I do so. What do I have to do in order to target the json inside the src folder, and not create any new files?

how can i get all of sabre hotel images, not all area returning images only logo

am trying to fetch sabre hotel images with the get availablle hotel api(https://api.cert.platform.sabre.com/v5/get/hotelavail)… but only few of the results contains the hotelRefInfo

only few of the results contains the HotelRefInfo;
it tried using the get hotel images to see if i can add the images by making two API calls but same result….

i have tried to change the categories but still

PHP code issue causing grid container and bootstrap 5 cards (grid-items) not to render on web-page loading?

I am trying to create a grid container that will dynamically display bootstrap cards of treeseed items that I added to MySQL database.The items should be displayed on the shop portion of a webpage I am making for arboretum I can make a connection to the database and get data back but from the moment I included DOMDocument elements within the code I have not got the expected output.

//shopconnect.php

$domDoc = new DOMDocument();
function generateTreeCard(){
  // global $domDoc;
  $topicDiv = $GLOBALS['domDoc']->createElement('div'); 
  $topicDiv->setAttribute('class','tree-card'); //tree-card div is to be appended to the container mt-3
  return $topicDiv; //DONE ALREADY AT END OF THE LOOP BELOW
}

function generateCardBody(){
  $cardBody = $GLOBALS['domDoc']->createElement('div');
  $cardBody->setAttribute('class','card-body');
  return $cardBody;  //DONE ALREADY APPENDED TO TREECARD BELOW IN THE LOOP
}


function addheaderH4Text($value){
  $cardTitle = $GLOBALS['domDoc']->createElement('h4',$value);//needs to be appended on to card body
  $cardTitle->setAttribute('class','card-title');//needs to be appended on to card body
  return $cardTitle; //ALREADY DONE IN THE LOOP BELOW
}

function generateInfoText(){
  $information = $GLOBALS['domDoc']->createElement('p','Information:');
  $information->setAttribute('class','info-text:');
  return $information; //DONE ALREADY IN LOOP BELOW VIA INFO PARAGRAPH VARIABLE
}

function generateListElements($key,$value){
  $resultItem = "";
  switch($key){
    case "commonName":
      $resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value"); 
      break;
    case "speciesName":
      $resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value"); 
      break;
    case "family":
      $resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value"); 
      break;
    case "seedcostInclVAT":
      $resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value"); 
      break;
    case "quantityInStock":
      $resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value"); 
      break;
    case "seedNumberPerPack":
      $resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value"); 
      break;
    case "colour":
      $resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value"); 
      break;
    case "hardiness":
      $resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value"); 
      break;
    case "soilType":
      $resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value"); 
      break;
    case "soilAcidity":
      $resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value"); 
      break;
    case "description":
      $resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value"); 
    break;
  }
  return $resultItem; //needs to be appended to the productInfoList variable <ul>
}

$outerContainer = $domDoc->createElement('div');
$outerContainer->setAttribute('class','items-wrapper');

$productInfoList = $domDoc->createElement('ul');
$listElementResult = "";

$imgCollectorArr = [];
$h4Text = "";
$cardBody = "";
$treeCard = "";
$treeImage1 = "";
$infoParagraph = "";
$cardContainer = "";

portion of code causing issues (shown below) is the nested foreach loop. I am using the functions above to create the DOM elements necessary to build the bootstrap cards (items) dynamically. 

foreach($treeSeedArr as $key => $value){
   $infoParagraph = generateInfoText(); //Just to display "Information:"
  foreach($value as $key1 => $value1){
     echo $key1 . " has a value of " . $value1 . "<br/>";
     if($key1 === 'commonName'){
      $h4Text = addheaderH4Text($value1); //GENERATE h4 text line'
      $cardBody = generateCardBody()->appendChild($h4Text)->appendChild($infoParagraph);
     }
     if($key1 !== 'id' && $key1 !== 'treeImage1' && $key1 !== 'treeImage2' && $key1 !== 'treeImage3'){
       $listElementResult = generateListElements($key1,$value1); // the bullet pointed list of properties
       $productInfoList->appendChild($listElementResult);//this is the <ul> tag
     }
     if($key1 === 'treeImage1' && !(is_null($value["treeImage1"]))){

        if(array_key_exists("treeImage2",$value) && !(is_null($value["treeImage2"]))){
          $imgCollectorArr["treeImage1"] = $value[$key1];
          continue; //if a treeseed has more at least 2 images 
        }
        $treeImage1 = generatetreeImage1($value1); //this is if a treeseed only has one image
        $treeCard = generateTreeCard()->appendChild($treeImage1)->appendChild($cardBody);
     }

     if($key1 === 'treeImage2' && !(is_null($value["treeImage2"]))){
        if(array_key_exists("treeImage3",$value) && !(is_null($value["treeImage3"]))){
          $imgCollectorArr["treeImage2"] = $value[$key1];
          continue; //if a treeseed has 3 images instead of 2
        }
         //design what happens when there are 2 images
         $slideBox1 = $domDoc->createElement('div');
         $slideBox1->setAttribute('class','mySlides fade');
         $countText1 = $domDoc->createElement('div','1 / 2');
         $countText1->setAttribute('class','numbertext');
         $slideBox1->appendChild($countText1);
         $firstImg = $domDoc->createElement('img');
         $firstImg->setAttribute('style','width:100%');
         $firstImg->setAttribute('src',$imgCollectorArr["treeImage1"]);
         $slideBox1->appendChild($firstImg);

         $slideBox2 = $domDoc->createElement('div');
         $slideBox2->setAttribute('class','mySlides fade');
         $countText2 = $domDoc->createElement('div','2 / 2');
         $countText2->setAttribute('class','numbertext');
         $slideBox2->appendChild($countText2);
         $secondImg = $domDoc->createElement('img');
         $secondImg->setAttribute('style','width:100%');
         $secondImg->setAttribute('src',"$value1");
         $slideBox2->appendChild($secondImg);
        
          $treeCard->appendChild($slideBox1);
          $treeCard->appendChild($slideBox2);

        //attach on to treecard
        $previousLink = $domDoc->createElement('a','&#10094;');
        $previousLink->setAttribute('class','prev');
        $previousLInk->setAttribute('onclick','plusSlides(-1)');

        $forwardLink = $domDoc->createElement('a','&#10095;');
        $forwardLink->setAttribute('class','next');
        $forwardLInk->setAttribute('onclick','plusSlides(1)');
        $treeCard->appendChild($previousLink);
        $treeCard->appendChild($forwardLink);


          //dots/circles
      $dotCircleBox1 = $domDoc->createElement('div');
      $dotCircleBox1->setAttribute('style','text-align:center');
      $dotSpanA = $domDoc->createElement('span');
      $dotSpanA->setAttribute('class','dot');
      $dotSpanA->setAttribute('onclick','currentSlide(1)');


      $dotSpanB = $domDoc->createElement('span');
      $dotSpanB->setAttribute('class','dot');
      $dotSpanB->setAttribute('onclick','currentSlide(2)');

      $dotCircleBox1->appendChild($dotSpanA);
      $dotCircleBox1->appendChild($dotSpanB);
      $treeCard->appendChild($dotCircleBox1);
     }

     if($key1 === 'treeImage3' && !(is_null($value[$key1]))){
      $slideBoxA = $domDoc->createElement('div');
      $slideBoxA->setAttribute('class','mySlides fade');
      $countTextA = $domDoc->createElement('div','1 / 3');
      $countTextA->setAttribute('class','numbertext');
      $slideBox1->appendChild($countTextA);
      $firstImg = $domDoc->createElement('img');
      $firstImg->setAttribute('style','width:100%');
      $firstImg->setAttribute('src',$imgCollectorArr["treeImage1"]);
      $slideBoxA->appendChild($firstImg);

      $slideBoxB = $domDoc->createElement('div');
      $slideBoxB->setAttribute('class','mySlides fade');
      $countTextB = $domDoc->createElement('div','2 / 3');
      $countTextB->setAttribute('class','numbertext');
      $slideBoxB->appendChild($countTextB);
      $secondImg = $domDoc->createElement('img');
      $secondImg->setAttribute('style','width:100%');
      $secondImg->setAttribute('src',$imgCollectorArr["treeImage2"]);
      $slideBoxB->appendChild($secondImg);

      $slideBoxC = $domDoc->createElement('div');
      $slideBoxC->setAttribute('class','mySlides fade');
      $countTextC = $domDoc->createElement('div','3 / 3');
      $countTextC->setAttribute('class','numbertext');
      $slideBoxC->appendChild($countTextB);
      $thirdImg = $domDoc->createElement('img');
      $thirdImg->setAttribute('style','width:100%');
      $thirdImg->setAttribute('src',$value1);
      $slideBoxC->appendChild($thirdImg);

      $treeCard->appendChild($slideBoxA);
      $treeCard->appendChild($slideBoxB);
      $treeCard->appendChild($slideBoxC);


      $previousLink = $domDoc->createElement('a','&#10094;');
      $previousLink->setAttribute('class','prev');
      $previousLInk->setAttribute('onclick','plusSlides(-1)');

      $forwardLink = $domDoc->createElement('a','&#10095;');
      $forwardLink->setAttribute('class','next');
      $forwardLInk->setAttribute('onclick','plusSlides(1)');

      $treeCard->appendChild($previousLink);
      $treeCard->appendChild($forwardLink);

      //dots/circles
      $dotCircleBox2 = $domDoc->createElement('div');
      $dotCircleBox2->setAttribute('style','text-align:center');
      $dotSpan1 = $domDoc->createElement('span');
      $dotSpan1->setAttribute('class','dot');
      $dotSpan1->setAttribute('onclick','currentSlide(1)');


      $dotSpan2 = $domDoc->createElement('span');
      $dotSpan2->setAttribute('class','dot');
      $dotSpan2->setAttribute('onclick','currentSlide(2)');


      $dotSpan3 = $domDoc->createElement('span');
      $dotSpan3->setAttribute('class','dot');
      $dotSpan3->setAttribute('onclick','currentSlide(3)');

      $dotCircleBox2->appendChild($dotSpan1);
      $dotCircleBox2->appendChild($dotSpan2);
      $dotCircleBox2->appendChild($dotSpan3); 
      $treeCard->appendChild($dotCircleBox2);

      
     }
  }
    $cardBody->appendChild($productInfoList);
    $treeCard->appendChild($cardBody);
  //for the forward and backwards arrow heads
    $cardContainer = $domDoc->createElement('div');//needs to be appended to items-wrapper
    if(!(is_null($value["treeImage2"])) || !(is_null($value["treeImage3"]))){
      $cardContainer->setAttribute('class','container mt-3 slides-container'); 
    }else{
      $cardContainer->setAttribute('class','container mt-3'); 
    }
    
    $cardContainer->appendChild($treeCard);
  
  $outerContainer->appendChild($cardContainer);
}
$domDoc->appendChild($outerContainer);
$htmlString = $domDoc->saveHTML();
echo $htmlString;

//gardenshop.php (I require once shopconnect.php)

<!DOCTYPE html>
<html lang="en">
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta name="author" content="Jacob">
      <link rel="stylesheet" href="./gardenshop.css">
      <link rel="icon" href="../tree_icon.png">
      <script src="../node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
      <!-- <script src="./slidelogic.js"></script> -->
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" 
      integrity="sha512-SnH5WK+bZxgPHs44uWIX+LLJAJ9/2PkPKZ5QiAj6Ta86w+fsb2TkcmfRyVX3pBnMFcV7oQPJkl9QevSCWr3W6A==" 
      crossorigin="anonymous" referrerpolicy="no-referrer" />
    </head>
    <body>
       <header>
         <div class="img-container"></div>
         <section class="shop-header"><h1>SPROUTY'S GARDENING SHOP</h1></section>
         <ul class="header-grp">
           <li class="header-item"><a id="back-link" href="./homepage.html"><i id="header-arrow" class="fa-solid fa-arrow-left-long"></i>Back To Homepage</a></li>
           <li class="header-item"><i class="fa-solid fa-cart-shopping"></i></li>
         </ul>
       </header>
       <main>
          <div class="f-container">
            <div class="box-1">
              <dl>
                <dt class="inline-dt">Contains Stainless Steel</dt>:&nbsp<input type="checkbox" class="filter-checkbox" id="tool_stainlessstl" name="tool_stainlessstl"/>
                <dt class="inline-dt">FSC &#40;Forest Stewardship Council&#41; certified</dt>:&nbsp<input type="checkbox" class="filter-checkbox" id="tool_fsc_cert" name="tool_fsc_cert"/>
                <dt class="inline-dt">In Stock</dt>:&nbsp<input type="checkbox" class="filter-checkbox" id="tool_stock" name="tool_stock"/>
              </dl>
             </div>
             <div class="box-2">
               <dl>
                <dt class="inline-dt">In Stock</dt>:&nbsp<input type="checkbox" class="filter-checkbox" id="giftcard_stock" name="giftcard_stock"/>
                <dt class="inline-dt">Weight &#40;grams&#41;</dt>:&nbsp<input type="range" min="0" max="50" id="giftcard_weight" name="giftcard_weight"/>
                <dt class="inline-dt">Price</dt>:&nbsp<input type="range" min="0" max="30" step="0.01" id="giftcard_price" name="giftcard_price"/>  
                <dt class="inline-dt">FSC &#40;Forest Stewardship Council&#41; certified</dt>:&nbsp<input type="checkbox" class="filter-checkbox" id="giftcard_fsc_cert" name="giftcard_fsc_cert"/>
               </dl>
             </div>
             <div class="box-3">
              <dl>
                <dt class="inline-dt">In Stock</dt>:&nbsp<input type="checkbox" class="filter-checkbox" id="fertiliser_stock" name="fertiliser_stock"/>
                <dt class="inline-dt">Litres &#40;Capacity&#41;</dt>:&nbsp<input type="range" min="10" max="60" id="fertiliser_capacity" name="fertiliser_capacity"/>
                <dt class="inline-dt">Price</dt>:&nbsp<input type="range" min="0" max="20" step="0.01" id="fertiliser_price" name="fertiliser_price"/>
              </dl>
             </div>
             <div class="box-4">
              <dl>
                <dt class="inline-dt">In Stock</dt>:&nbsp<input type="checkbox" id="treeseed_stock" name="treeseed_stock"/>
                <dt class="inline-dt">Soil Type</dt>:&nbsp<select name="soiltypes" id="soiltypes">
                  <option value="chalk">chalk</option>
                  <option value="sand">sand</option>
                  <option value="loam">loam</option>
                  <option value="clay">clay</option>
                </select>
                <dt class="inline-dt">Soil Acidity</dt>:&nbsp<select name="soilacidity" id="soilacidity">
                  <option value="acid">acid</option>
                  <option value="alkaline">alkaline</option>
                  <option value="neutral">neutral</option>
                </select>
                <dt class="inline-dt">Hardiness</dt>:&nbsp<select name="hardiness" id="hardiness">
                  <option value="hardy">hardy</option>
                  <option value="tender">tender</option>
                  <option value="hardy/half-hardy">hardy/half-hardy</option>
                </select>
                <dt class="inline-dt">Price</dt>:&nbsp<input type="range" min="0" max="4" step="0.01" id="treeseed_price" name="treeseed_price"/>

              </dl>
             </div>
             <div class="box-5">
              <dl>
                 <dt class="inline-dt">In Stock</dt>:&nbsp<input type="checkbox" id="compost_stock" name="compost_stock"/>
                 <dt class="inline-dt">Is Biodegradable</dt>:&nbsp<input type="checkbox" class="filter-checkbox" id="compost_degradable" name="compost_degradable"/>
                 <dt class="inline-dt">Litres &#40;Capacity&#41;</dt>:&nbsp<span><input type="range" min="0" max="280" id="compost_capacity" name="compost_capacity"/>
                 <dt class="inline-dt">Price</dt>:&nbsp<input type="range" min="0" max="20" step="0.01" id="compost_price" name="compost_price"/>
              </dl>
            </div>
          </div>
            <?php require_once './shopconnect.php'; ?>
            <script type="text/javascript" src="./slidelogic.js"></script>

       </main>

    </body>
</html>

I added conditional if statements inside the nested foreach loops to create bootstrap cards that could hold a standalone treeimage or more than one treeimage in which case each card would have a slideshow.

Unfortunately the output is the following and the console in my Chrome browser shows no errors:

No grid rendered on webpage loading

How to update map coordinates after zooming in Leaflet?

I am new to working with maps. I have currently implemented a feature that allows users to draw an area on the map, which gets marked. What I need is for, when the user zooms in on the map while drawing, the geographic coordinates to be updated to reflect the new visible area on the map.

Currently, when the user zooms in while drawing, the final mark refers to the initial coordinates before the zoom, resulting in a marked area that is different from what the drawing currently shows.

I am working with Leaflet and Leaflet.draw.

My intention was to capture the pixel points of the drawing before the zoom and then convert them back to geographic coordinates after the zoom. However, it seems that this is not working, as the coordinates remain the same. Below is a part of the code where the coordinates are captured before creating the marker.

Basically, I need latlngs to contain the updated coordinates after the zoom, so I can pass them as parameters to create the marker.

        let isZoomed = false;

        map.on("zoomend", () => {
          isZoomed = true;
        });


        freeDraw.on('markers', (event: any) => {
          if (event.eventType == 'create' && event.target.map.drawLatLngs) {
            var latlngs = event.target.map.drawLatLngs;
            handleNewPolyline(latlngs);
          }

          if (event.eventType == 'create' && event.latLngs && event.latLngs.length > 0) {
            let latlngs: any = event.latLngs;
            let newPoints:any = [];

            let initialPoints = latlngs
            .flatMap((polygon: any) =>
              polygon.map((coord: any)=> map.latLngToLayerPoint(coord))
            );

            if (isZoomed) {
              newPoints = initialPoints.map((point: any) => map.layerPointToLatLng(point));
              latlngs = newPoints;             
              isZoomed = false;
              newPoints = [];
            } else {
              latlngs = event.latLngs;
            }

npm install is giving error – npm error ERESOLVE unable to resolve dependency tree

In my React Native with TypeScript project, I wanted to install dependencies.

To install Testing Libraries I’ve used this command:
npm install @testing-library/react-native @testing-library/jest-native –save-dev

**But it's giving me this error:**

npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: [email protected]
npm error Found: [email protected]
npm error node_modules/react
npm error   react@"18.2.0" from the root project
npm error   peer react@">=16.8.0" from @testing-library/[email protected]
npm error   node_modules/@testing-library/react-native
npm error     dev @testing-library/react-native@"*" from the root project
npm error   1 more (react-native)
npm error
npm error Could not resolve dependency:
npm error peer react@"^18.3.1" from [email protected]
npm error node_modules/react-test-renderer
npm error   peer react-test-renderer@">=16.8.0" from @testing-library/[email protected]
npm error   node_modules/@testing-library/react-native
npm error     dev @testing-library/react-native@"*" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps

— I’ve also tried –legacy-peer-deps but, then npm install is not working and I’m not sure what’s wrong.

===> Output of npm ls react-dom:

[email protected] /Users/App
└── (empty)

===> Output of npm ls react:

[email protected] /Users/****/App
├─┬ @testing-library/[email protected]
│ └── [email protected] deduped
├─┬ @testing-library/[email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ ├─┬ @react-native/[email protected]
│ │ └── [email protected] deduped
│ ├─┬ [email protected]
│ │ └── [email protected] deduped
│ └── [email protected] deduped
└── [email protected]

I’ve tried –legacy-peer-deps, it’s working temporary but when I try to add ESLint, it’s again giving me error.

npm error code ERESOLVE
npm error ERESOLVE could not resolve
npm error
npm error While resolving: @testing-library/[email protected]
npm error Found: [email protected]

What is different in my Ajax vs XMLHttpRequest Call that lets my Server understand Ajax but not XMLHttpRequest?

I have a very simple server call like this:

[HttpPost]
[AllowAnonymous]
public JsonResult Test(TestRequestModel requestModel)
{
    //do stuff
    return Json(new { result.Success });
}

My TestRequestModel looks like this:

public class TestRequestModel
{
    public string Email { get; set; } = string.Empty;
}

I am trying to do a POST request to the server. But for a complex list of reasons I need to be using XMLHttpRequest instead of $.ajax. To do this I am going to show you how I did it in ajax and then how I did it with XMLHttpRequest.

First here is how I call my server:

function MyTestFunction() {
   let parameters = {
       Email: "[email protected]"
   }

    CallServer(function () {
        //Do stuff
    }, function () {
        //Do other stuff
    }, "/Home/Test", parameters)
}

Ajax:

function CallServer(resolve, reject, path, parameters) {
    $.ajax({
        type: "POST",
        url: path,
        data: AddAntiForgeryToken(parameters),
        success: function (response) {
            //do stuff
        },
        error: function (xhr) {
            //do stuff
        },
        complete: function () {
            //do more stuff
        }
    });
}

XMLHttpRequest Way:

function CallServer(resolve, reject, path, parameters) {
    let xhr = new XMLHttpRequest();

    xhr.open("POST", path, true);
    xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
    xhr.setRequestHeader('RequestVerificationToken', GetMyToken());
    xhr.onreadystatechange = function (e) {
        if (xhr.readyState === XMLHttpRequest.DONE) {
            if (xhr.status === 200 || xhr.status === 201) {
                //do stuff
            }
            else {
                //do other stuff
            }
        }
    };
    
    xhr.send(JSON.stringify(parameters));
}

If I run the above code the ajax way, then it works without issues. If I try to do it the XMLHttpRequest way then my request model gets created but the Email field is not populated. Now I found that I can solve this by adding [FromBody] on the request model and it does work, I tested it and no problems.

Also, as I read online and hopefully understood correctly, but ajax uses XMLHttpRequest behind the hood right?

So why do I have to add [FromBody] on my controller for this to work? Is there a way I can modify my XMLHttpRequest so that it is not needed? The solution I am looking for how to not have to specify [FromBody] on a json post request to .net core server.

Highchart vertical and horizontal scrollbar

I have dependency information that I would like to show on a web page using Highcharts. I chose Treegraph chart as I think it’s more suitable for what I need it for. This is the link to a demo https://www.highcharts.com/demo/highcharts/treegraph-chart.

The issue I have and I couldn’t overcome on my own is that when there are lots of branches and Leaves then the whole graph will get squeezed to show everything in one view. jsfiddle for code below is available in the link above.

Highcharts.chart('container', {
    chart: {
        spacingBottom: 30,
        marginRight: 120,
        height: 1200,
        scrollablePlotArea: {
            minWidth: 1500, // Set minimum width for horizontal scrolling
            minHeight: 1200 // Set minimum height for vertical scrolling
        }
    },
    title: {
        text: 'Phylogenetic language tree'
    },
    series: [
        {
            type: 'treegraph',
            keys: ['parent', 'id', 'level', 'color'], // Add color to keys
            clip: false,
            data: [
                [undefined, 'Proto Indo-European'],
                ['Proto Indo-European', 'Balto-Slavic'],
                ['Proto Indo-European', 'Germanic'],
                ['Proto Indo-European', 'Celtic'],
                ['Proto Indo-European', 'Italic'],
                ['Proto Indo-European', 'Hellenic'],
                ['Proto Indo-European', 'Anatolian'],
                ['Proto Indo-European', 'Indo-Iranian'],
                ['Proto Indo-European', 'Tocharian'],
                ['Indo-Iranian', 'Dardic'],
                ['Indo-Iranian', 'Indic'],
                ['Indo-Iranian', 'Iranian'],
                ['Iranian', 'Old Persian'],
                ['Old Persian', 'Middle Persian'],
                ['Indic', 'Sanskrit'],
                ['Italic', 'Osco-Umbrian'],
                ['Italic', 'Latino-Faliscan'],
                ['Latino-Faliscan', 'Latin'],
                ['Celtic', 'Brythonic'],
                ['Celtic', 'Goidelic'],
                ['Germanic', 'North Germanic'],
                ['Germanic', 'West Germanic'],
                ['Germanic', 'East Germanic'],
                ['North Germanic', 'Old Norse'],
                ['North Germanic', 'Old Swedish'],
                ['North Germanic', 'Old Danish'],
                ['West Germanic', 'Old English'],
                ['West Germanic', 'Old Frisian'],
                ['West Germanic', 'Old Dutch'],
                ['West Germanic', 'Old Low German'],
                ['West Germanic', 'Old High German'],
                ['Old Norse', 'Old Icelandic'],
                ['Old Norse', 'Old Norwegian'],
                ['Old Swedish', 'Middle Swedish'],
                ['Old Danish', 'Middle Danish'],
                ['Old English', 'Middle English'],
                ['Old Dutch', 'Middle Dutch'],
                ['Old Low German', 'Middle Low German'],
                ['Old High German', 'Middle High German'],
                ['Balto-Slavic', 'Baltic'],
                ['Balto-Slavic', 'Slavic'],
                ['Slavic', 'East Slavic'],
                ['Slavic', 'West Slavic'],
                ['Slavic', 'South Slavic'],
                ['Polish', 'POLISH2'],
                ['PPPPPPPPP1', 'QQQQQQQQQ'],
                // Leaves:
                ['Proto Indo-European', 'Phrygian', 6],
                ['Proto Indo-European', 'Armenian', 6],
                ['Proto Indo-European', 'Albanian', 6],
                ['Proto Indo-European', 'Thracian', 6],
                ['Tocharian', 'Tocharian A', 6],
                ['Tocharian', 'Tocharian B', 6],
                ['Anatolian', 'Hittite', 6],
                ['Anatolian', 'Palaic', 6],
                ['Anatolian', 'Luwic', 6],
                ['Anatolian', 'Lydian', 6],
                ['Iranian', 'Balochi', 6],
                ['Iranian', 'Kurdish', 6],
                ['Iranian', 'Kurdish', 6],
                ['Iranian', 'Kurdish', 6],
                ['Iranian', 'Kurdish', 6],
                ['Iranian', 'Kurdish', 6],
                ['Iranian', 'Kurdish', 6],
                ['Iranian', 'Kurdish', 6],
                ['Iranian', 'Kurdish', 6],
                ['Iranian', 'Kurdish', 6],
                ['Iranian', 'Kurdish', 6],
                ['Iranian', 'Kurdish', 6],
                ['Iranian', 'Kurdish', 6],
                ['Iranian', 'Pashto', 6],
                ['Iranian', 'Sogdian', 6],
                ['Old Persian', 'Pahlavi', 6],
                ['Middle Persian', 'Persian', 6],
                ['Hellenic', 'Greek', 6],
                ['Dardic', 'Dard', 6],
                ['Sanskrit', 'Sindhi', 6],
                ['Sanskrit', 'Romani', 6],
                ['Sanskrit', 'Urdu', 6],
                ['Sanskrit', 'Hindi', 6],
                ['Sanskrit', 'Bihari', 6],
                ['Sanskrit', 'Assamese', 6],
                ['Sanskrit', 'Bengali', 6],
                ['Sanskrit', 'Marathi', 6],
                ['Sanskrit', 'Gujarati', 6],
                ['Sanskrit', 'Punjabi', 6],
                ['Sanskrit', 'Sinhalese', 6],
                ['Osco-Umbrian', 'Umbrian', 6],
                ['Osco-Umbrian', 'Oscan', 6],
                ['Latino-Faliscan', 'Faliscan', 6],
                ['Latin', 'Portugese', 6],
                ['Latin', 'Spanish', 6],
                ['Latin', 'French', 6],
                ['Latin', 'Romanian', 6],
                ['Latin', 'Italian', 6],
                ['Latin', 'Catalan', 6],
                ['Latin', 'Franco-Provençal', 6],
                ['Latin', 'Rhaeto-Romance', 6],
                ['Brythonic', 'Welsh', 6],
                ['Brythonic', 'Breton', 6],
                ['Brythonic', 'Cornish', 6],
                ['Brythonic', 'Cuymbric', 6],
                ['Goidelic', 'Modern Irish', 6],
                ['Goidelic', 'Scottish Gaelic', 6],
                ['Goidelic', 'Manx', 6],
                ['East Germanic', 'Gothic', 6],
                ['Middle Low German', 'Low German', 6],
                ['Middle High German', '(High) German', 6],
                ['Middle High German', 'Yiddish', 6],
                ['Middle English', 'English', 6],
                ['Middle Dutch', 'Hollandic', 6],
                ['Middle Dutch', 'Flemish', 6],
                ['Middle Dutch', 'Dutch', 6],
                ['Middle Dutch', 'Limburgish', 6],
                ['Middle Dutch', 'Brabantian', 6],
                ['Middle Dutch', 'Rhinelandic', 6],
                ['Old Frisian', 'Frisian', 6],
                ['Middle Danish', 'Danish', 6],
                ['Middle Swedish', 'Swedish', 6],
                ['Old Norwegian', 'Norwegian', 6],
                ['Old Norse', 'Faroese', 6],
                ['Old Icelandic', 'Icelandic', 6],
                ['Baltic', 'Old Prussian', 6],
                ['Baltic', 'Lithuanian', 6],
                ['Baltic', 'Latvian', 6],
                ['West Slavic', 'Polish', 6],
                ['POLISH2', 'PPPPPPPPP', 6],
                ['POLISH2', 'PPPPPPPPP', 6],
                ['POLISH2', 'PPPPPPPPP', 6],
                ['POLISH2', 'PPPPPPPPP1', 6],
                ['POLISH2', 'PPPPPPPPP', 6],
                ['POLISH2', 'PPPPPPPPP', 6],
                ['POLISH2', 'PPPPPPPPP', 6],
                ['POLISH2', 'PPPPPPPPP', 6],
                ['QQQQQQQQQ', '_=========_', 6],
                
                ['West Slavic', 'Slovak', 6],
                ['West Slavic', 'Czech', 6],
                ['West Slavic', 'Wendish', 6],
                ['East Slavic', 'Bulgarian', 6],
                ['East Slavic', 'Old Church Slavonic', 6],
                ['East Slavic', 'Macedonian', 6],
                ['East Slavic', 'Serbo-Croatian', 6],
                ['East Slavic', 'Slovene', 6],
                ['South Slavic', 'Russian', 6],
                ['South Slavic', 'Ukrainian', 6],
                ['South Slavic', 'Belarusian', 6],
                ['South Slavic', 'Rusyn', 6]
            ],
            marker: {
                symbol: 'circle',
                radius: 6,
                fillColor: '#ffffff',
                lineWidth: 3
            },
            dataLabels: {
                align: 'left',
                pointFormat: '{point.id}',
                style: {
                    color: '#000000',
                    textOutline: '3px #ffffff',
                    whiteSpace: 'nowrap'
                },
                x: 24,
                crop: false,
                overflow: 'none'
            },
            levels: [
                {
                    level: 1,
                    levelIsConstant: false,
                    colorByPoint: true
                },
                {
                    level: 2,
                    colorVariation: {
                        key: 'brightness',
                        to: -0.5
                    }
                },
                {
                    level: 3,
                    colorVariation: {
                        key: 'brightness',
                        to: 0.5
                    }
                },
                {
                    level: 6,
                    dataLabels: {
                        x: 10
                    },
                    marker: {
                        radius: 4
                    }
                }
            ]
        }
    ]
});


document.getElementById('container').style.overflow = 'auto';
document.getElementById('container').style.width = '100%';
document.getElementById('container').style.height = '800px';

How can I avoid the squeezing and add like a vertical and horizontal scrollbar? and as the graph grow vertically or horizontally instead of putting stuff on one another, grow the graph and add scrollbars(or maybe the ability to move the graph by dragging the graph).

I have been stuck on this for two days and it seems that I cannot figure it out on my own. I would appreciate any help. I’m not a web developer or a UI designer so please forgive any obvious thing that I might have missed.

Thanks

Chart JS Curved Labels in Polar Area

I am working on a web project using Chart.js to create a PolarArea chart that dynamically updates based on the selected class from a dropdown menu. I have encountered an issue where the labels are dynamic, but I need it to be static

  const subjects = {
5: ["Укр. мова", "Укр. літ.", "Заруб. літ.", "Англ. мова", "Історія", "Математика", "Природа", "ІТ", "Фізкультура", "Мистецтво"],
6: ["Укр. мова", "Укр. літ.", "Заруб. літ.", "Англ. мова", "Історія", "Математика", "Природа", "ІТ", "Географія", "Фізкультура", "Мистецтво"],
7: ["Укр. мова", "Укр. літ.", "Заруб. літ.", "Англ. мова", "Всесвіт. історія", "Історія Укр.", "Алгебра", "Геометрія", "ІТ", "Біологія", "Географія", "Фізика", "Хімія", "Здоров'я", "Мистецтво", "Фізкультура"],
8: ["Укр. мова", "Укр. літ.", "Заруб. літ.", "Англ. мова", "Всесвіт. історія", "Історія Укр.", "Алгебра", "Геометрія", "ІТ", "Біологія", "Географія", "Фізика", "Хімія", "Здоров'я", "Мистецтво", "Фізкультура"],
9: ["Укр. мова", "Укр. літ.", "Заруб. літ.", "Англ. мова", "Всесвіт. історія", "Історія Укр.", "Алгебра", "Геометрія", "ІТ", "Біологія", "Географія", "Фізика", "Хімія", "Здоров'я", "Мистецтво", "Фізкультура"],
10: ["Укр. мова", "Укр. літ.", "Заруб. літ.", "Англ. мова", "Всесвіт. історія", "Історія Укр.", "Алгебра", "Геометрія", "ІТ", "Біологія", "Географія", "Фізика", "Хімія", "Здоров'я", "Мистецтво", "Фізкультура"],
11: ["Укр. мова", "Укр. літ.", "Заруб. літ.", "Англ. мова", "Всесвіт. історія", "Історія Укр.", "Алгебра", "Геометрія", "ІТ", "Біологія", "Географія", "Фізика", "Хімія", "Здоров'я", "Мистецтво", "Фізкультура"]

};

    const data = {
        labels: [],
        datasets: [{
            data: [],
            backgroundColor: [],
            borderColor: 'rgba(54, 162, 235, 0.7)',
            borderWidth: 1
        }]
    };

    const ctx = document.getElementById('myChart').getContext('2d');
    const myChart = new Chart(ctx, {
type: 'polarArea',
data: data,
options: {
    responsive: true,
    maintainAspectRatio: false,
    
    layout: {
        padding: {
            top: 30,
            bottom: 30,
            left: 30,
            right: 30
        }
    },
    scales: {
        r: {
            min: 1, // мінімальне значення
            max: 12,
            ticks: {
                stepSize: 1, 
                color: '#000', // колір поділок
                backdropColor: 'rgba(255,255,255,0.8)', // фон під поділками
                font: {
                    size: 14 // розмір шрифту для поділок
                }
            },
            grid: {
                color: '#888', // колір сітки
                circular: true
            },
        }
    },
    plugins: {
        legend: {
            display: false
        },
        labels: {
            size: 1,
            render: 'label',
            arc: true,
            fontColor: '#000',
            position: 'outside'
        }
    }
}

});
I’ve tied everything, but nothing works