JSFiddle - React, Tailwind, and code Playground

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Address Geocoding and CSV Export</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
        }
        textarea {
            width: 100%;
            height: 150px;
            margin-bottom: 20px;
        }
        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 20px;
        }
        table, th, td {
            border: 1px solid black;
        }
        th, td {
            padding: 8px;
            text-align: left;
        }
        .invalid {
            background-color: lightcoral;
        }
        button {
            margin-top: 10px;
            padding: 10px 15px;
            font-size: 16px;
            cursor: pointer;
        }
        #progress-container {
            margin-top: 20px;
            width: 100%;
            background-color: #f3f3f3;
            border: 1px solid #ccc;
            border-radius: 5px;
            overflow: hidden;
            height: 25px;
        }
        #progress-bar {
            height: 100%;
            width: 0%;
            background-color: #4caf50;
            text-align: center;
            line-height: 25px;
            color: white;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <h1>Address Geocoding and CSV Export</h1>
    <p>Enter addresses (one per line):</p>
    <textarea id="addressInput" placeholder="Enter addresses here..."></textarea>
    <button onclick="geocodeAddresses()">Geocode Addresses</button>
    <button onclick="downloadCSV()">Download as CSV</button>

    <div id="progress-container">
        <div id="progress-bar">0%</div>
    </div>

    <h2>Geocoded Results:</h2>
    <table id="resultTable">
        <thead>
            <tr>
                <th>Input Address</th>
                <th>Street Number</th>
    ...

JavaScript

const express = require('express');
const cors = require('cors');
const { Connection, Request, TYPES } = require('tedious'); // Ensure TYPES is imported
const path = require('path'); // Import path module to resolve file paths

// Initialize Express app
const app = express();
app.use(cors());
app.use(express.json()); // To parse JSON request bodies

// Server configuration
const PORT = 3000;

// Database configuration using NTLM (Windows Authentication)
const config = {
    server: 'REXT21',
    options: {
        database: 'SPATIAL',
        port: 1433,   
        encrypt: false, 
        trustServerCertificate: true,  
    },
    authentication: {
        type: 'ntlm',
        options: {
            domain: 'TEST-NET',     
            userName: 'MILO',     
            password: 'Setter4', 
        },
    },
};

// Create the connection
const connection = new Connection(config);

let isConnected = false;

// Ensure the connection is fully established before starting any requests
connection.on('connect', (err) => {
  if (err) {
    console.error('Connection Failed:', err);
  } else {
    console.log('Connected to SQL Server');
    isConnected = true;
  }
});

// Connect to the database
connection.connect();

// Endpoint to handle geocoding requests
app.post('/geocode', async (req, res) => {
  const { addresses } = req.body;

  if (!addresses || !Array.isArray(addresses) || address.length === 0) {
    return res.status(400).json({ error: 'At least one address is required' });
  }

  if (!isConnected) {
    return res.status(500).json({ error: 'Database not connected' });
  }

  let results = [];
  let processedCount = 0;

  // Process each address asynchronously
  for (const streetName of addresses) {

    // SQL query with additional logic to handle addresses without commas
    const sqlQuery = `
      SELECT TOP 1 LATITUDE, LONGITUDE, FULL_ADD, NAME
      FROM Addresses_p
      WHERE @streetName = NAME
    `;

    const request = new Request(sqlQuery, (err) =>...