I am having a problem with my azure web app (linux) while trying to add data into my sql database
Here are the errors im getting:
DataAdd.js:26
POST https://website.azurewebsites.net:5000/add-data net::ERR_CONNECTION_TIMED_OUT
Error: TypeError: Failed to fetch
at handleSubmit (DataAdd.js:26:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
at invokeGuardedCallback (react-dom.development.js:4277:1)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:4291:1)
at executeDispatch (react-dom.development.js:9041:1)
at processDispatchQueueItemsInOrder (react-dom.development.js:9073:1)
at processDispatchQueue (react-dom.development.js:9086:1)
at dispatchEventsForPlugins (react-dom.development.js:9097:1)
at react-dom.development.js:9288:1
WebSocketClient.js:13 WebSocket connection to 'wss://website.azurewebsites.net:8080/ws' failed:
Here is my DataAdd.js code:
import React, { useState } from 'react';
import './DataAdd.css';
const DataAdd = () => {
const [formData, setFormData] = useState({
description: '',
Nimi: '',
Syntymäaika: '',
Rotu: '',
Sukupuoli: '',
Rekisterinumero: '',
Omistaja: ''
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value
});
};
const handleSubmit = async (e) => {
e.preventDefault();
try {
const response = await fetch('https://website.azurewebsites.net:5000/add-data', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
});
if (response.ok) {
alert('Data added successfully');
setFormData({
description: '',
Nimi: '',
Syntymäaika: '',
Rotu: '',
Sukupuoli: '',
Rekisterinumero: '',
Omistaja: ''
});
} else {
alert('Error adding data');
}
} catch (error) {
console.error('Error:', error);
alert('Error adding data');
}
};
return (
<div>
<h1>Add Data</h1>
<form onSubmit={handleSubmit}>
<div>
<label>Description</label>
<input type="text" name="description" value={formData.description} onChange={handleChange} required />
</div>
<div>
<label>Nimi</label>
<input type="text" name="Nimi" value={formData.Nimi} onChange={handleChange} required />
</div>
<div>
<label>Syntymäaika</label>
<input type="date" name="Syntymäaika" value={formData.Syntymäaika} onChange={handleChange} required />
</div>
<div>
<label>Rotu</label>
<input type="text" name="Rotu" value={formData.Rotu} onChange={handleChange} required />
</div>
<div>
<label>Sukupuoli</label>
<input type="text" name="Sukupuoli" value={formData.Sukupuoli} onChange={handleChange} required />
</div>
<div>
<label>Rekisterinumero</label>
<input type="text" name="Rekisterinumero" value={formData.Rekisterinumero} onChange={handleChange} required />
</div>
<div>
<label>Omistaja</label>
<input type="text" name="Omistaja" value={formData.Omistaja} onChange={handleChange} required />
</div>
<button type="submit">Add Data</button>
</form>
</div>
);
};
export default DataAdd;
Here is my server.js code:
require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const sql = require('mssql');
const app = express();
const port = process.env.REACT_APP_AZURE_SERVER_PORT;
const config = {
user: process.env.REACT_APP_AZURE_SQL_USER,
password: process.env.REACT_APP_AZURE_SQL_PASSWORD,
server: process.env.REACT_APP_AZURE_SQL_SERVER,
port: parseInt(process.env.REACT_APP_AZURE_SQL_PORT, 10),
database: process.env.REACT_APP_AZURE_SQL_DATABASE,
authentication: {
type: 'default'
},
options: {
encrypt: true,
requestTimeout: 60000,
connectionTimeout: 30000
}
};
// Add CORS middleware
app.use(cors({
origin: 'https://website.azurewebsites.net', // Adjust based on your frontend URL
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
preflightContinue: false,
optionsSuccessStatus: 204
}));
// Add body parser middleware
app.use(express.json());
async function connectWithRetry() {
let retries = 5;
while (retries) {
try {
const pool = await sql.connect(config);
return pool;
} catch (err) {
console.log(`Connection failed, retries left: ${retries - 1}`);
console.error(err);
retries -= 1;
await new Promise(res => setTimeout(res, 5000)); // wait for 5 seconds before retrying
}
}
throw new Error('Could not connect to the database after multiple attempts');
}
connectWithRetry().then(pool => {
console.log("Connected to the database");
app.post('/add-data', async (req, res) => {
try {
console.log('Received request:', req.body);
const { description, Nimi, Syntymäaika, Rotu, Sukupuoli, Rekisterinumero, Omistaja } = req.body;
console.log('Connecting to database...');
const result = await pool.request()
.input('description', sql.NVarChar, description)
.input('Nimi', sql.NVarChar, Nimi)
.input('Syntymäaika', sql.Date, Syntymäaika)
.input('Rotu', sql.NVarChar, Rotu)
.input('Sukupuoli', sql.NVarChar, Sukupuoli)
.input('Rekisterinumero', sql.NVarChar, Rekisterinumero)
.input('Omistaja', sql.NVarChar, Omistaja)
.query(`
INSERT INTO dbo.hevoset (description, Nimi, Syntymäaika, Rotu, Sukupuoli, Rekisterinumero, Omistaja)
VALUES (@description, @Nimi, @Syntymäaika, @Rotu, @Sukupuoli, @Rekisterinumero, @Omistaja)
`);
console.log('Data added:', result);
res.status(200).send('Data added successfully');
} catch (err) {
console.error('Error adding data:', err);
res.status(500).send('Error adding data');
}
});
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
}).catch(err => {
console.error('Database connection failed: ', err.message);
});
What I have tried: Verified server is running: Server is running and logs indicate it is listening on the correct port.
Checked URL and port: Ensured that the URL and port in the React fetch call match the server's URL and port.
Configured CORS: Set CORS options to allow requests from the client URL.
Tested endpoint with curl/Postman: Direct requests to the server endpoint from curl/Postman work without issues.
Tested it on local, connection to the database works and so does adding data.
Added logging: Added logging to capture incoming requests and errors.
What I expect: I expect the POST request from my React application to successfully reach the SQL Server, allowing data to be added to the Azure SQL database.
Environment: Client: React web app hosted on Azure (Linux) Server: SQL server hosted on Azure Database: SQL database on Azure
I even tried to run your code but I get a WSS and CORS error, shown the same null data in adding. Then change your code as follows: the server-side logic stored in the backend code where we interact with db,api end points and process data.
I configured CORS to allow requests from all urls to the backend as shown here:
app.use(cors({
origin: '*',
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
preflightContinue: false,
optionsSuccessStatus: 204
}));
Change the INSERT
query like this to avoid null:
INSERT INTO hevoset (description, Nimi, Syntymäaika, Rotu, Sukupuoli, Rekisterinumero, Omistaja)
VALUES (?, ?, ?, ?, ?, ?, ?)
Backend:
require('dotenv').config();
const express = require('express');
const cors = require('cors');
const mysql = require('mysql2');
const fs = require('fs');
const app = express();
const port = process.env.PORT || 8001;
const config = {
host: process.env.DB_HOST,
user: process.env.DB_USER ,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
port: 3306,
ssl: {
ca: fs.readFileSync("DigiCertGlobalRootCA.crt.pem")
}
};
const conn = mysql.createConnection(config);
app.use(cors({
origin: '*',
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
preflightContinue: false,
optionsSuccessStatus: 204
}));
app.use(express.json());
async function connectWithRetry() {
let retries = 5;
while (retries) {
try {
conn.connect(err => {
if (err) {
throw err;
} else {
console.log("Connected to the database");
}
});
return;
} catch (err) {
console.log(`Connection failed, retries left: ${retries - 1}`);
console.error(err);
retries -= 1;
await new Promise(res => setTimeout(res, 5000));
}
}
throw new Error('Could not connect to the database after multiple attempts');
}
connectWithRetry().catch(err => {
console.error('Database connection failed: ', err.message);
});
app.post('/add-data', (req, res) => {
try {
console.log('Received request:', req.body);
const { description, Nimi, Syntymäaika, Rotu, Sukupuoli, Rekisterinumero, Omistaja } = req.body;
const sql = `
INSERT INTO hevoset (description, Nimi, Syntymäaika, Rotu, Sukupuoli, Rekisterinumero, Omistaja)
VALUES (?, ?, ?, ?, ?, ?, ?)
`;
conn.query(sql, [description, Nimi, Syntymäaika, Rotu, Sukupuoli, Rekisterinumero, Omistaja], (err, results) => {
if (err) {
console.error('Error adding data:', err);
res.status(500).send('Error adding data');
} else {
console.log('Data added:', results);
res.status(200).send('Data added successfully');
}
});
} catch (err) {
console.error('Error adding data:', err);
res.status(500).send('Error adding data');
}
});
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
The frontend code handles the user interface and user interactions for backend. I used axios
to connect backend as shown here:
const response = await axios.post('http://localhost:8001/add-data', formData);
Frontend:
import React, { useState } from 'react';
import axios from "axios";
import './DataAdd.css';
const DataAdd = () => {
const [formData, setFormData] = useState({
description: '',
Nimi: '',
Syntymäaika: '',
Rotu: '',
Sukupuoli: '',
Rekisterinumero: '',
Omistaja: ''
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value
});
};
const handleSubmit = async (e) => {
e.preventDefault();
try {
const response = await axios.post('http://localhost:8001/add-data', formData);
if (response.status === 200) {
alert('Data added successfully');
setFormData({
description: '',
Nimi: '',
Syntymäaika: '',
Rotu: '',
Sukupuoli: '',
Rekisterinumero: '',
Omistaja: ''
});
} else {
alert('Error adding data');
}
} catch (error) {
console.error('Error:', error);
alert('Error adding data');
}
};
return (
<div>
<h1>Add Data</h1>
<form onSubmit={handleSubmit}>
<div>
<label>Description</label>
<input type="text" name="description" value={formData.description} onChange={handleChange} required />
</div>
<div>
<label>Nimi</label>
<input type="text" name="Nimi" value={formData.Nimi} onChange={handleChange} required />
</div>
<div>
<label>Syntymäaika</label>
<input type="date" name="Syntymäaika" value={formData.Syntymäaika} onChange={handleChange} required />
</div>
<div>
<label>Rotu</label>
<input type="text" name="Rotu" value={formData.Rotu} onChange={handleChange} required />
</div>
<div>
<label>Sukupuoli</label>
<input type="text" name="Sukupuoli" value={formData.Sukupuoli} onChange={handleChange} required />
</div>
<div>
<label>Rekisterinumero</label>
<input type="text" name="Rekisterinumero" value={formData.Rekisterinumero} onChange={handleChange} required />
</div>
<div>
<label>Omistaja</label>
<input type="text" name="Omistaja" value={formData.Omistaja} onChange={handleChange} required />
</div>
<button type="submit">Add Data</button>
</form>
</div>
);
};
export default DataAdd;