Server side code:
//MUST HAVE MYSQL RUNNING ON YOUR PC, I HAVE BEEN USING XAMPP
const http = require('http');
const mysql = require('mysql2');
const url = require('url');
const cors = require('cors');
const querystring = require('querystring')
// MySQL DB Connection
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '', //You will need to change this password to whatever you have on your system,default to no password
database: 'USERSFINAL' //Might have to comment this out for the first initial setup to create database and table then add it back in
});
// Create database and tables for the first run
connection.query('CREATE DATABASE IF NOT EXISTS USERSFINAL', (err, result) => {
if (err) throw err;
connection.query('USE USERSFINAL', (err, result) => {
if (err) throw err;
connection.query('CREATE TABLE IF NOT EXISTS userInformation (id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(10), first_name VARCHAR(20), surname VARCHAR(20), mobile VARCHAR(15), email_address VARCHAR(40), addressLine1 VARCHAR(50), addressLine2 VARCHAR(50), town VARCHAR(20), county VARCHAR(20), eircode VARCHAR(20))', (err, result) => {
if (err) throw err;
console.log('Created database and userInformation table');
});
});
});
// Connect to MySQL DB
connection.connect((err) => {
if (err) throw err;
console.log('Connected to MySQL server');
});
// Create HTTP server
http.createServer((req, res) => {
const parsedUrl = url.parse(req.url, true);
const pathname = parsedUrl.pathname;
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PATCH, DELETE, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
// Handle GET requests, R part of CRUD
if (req.method === 'GET') {
// Retrieve all records, I added this route for testing for myself but I figure there is no harm in leaving it in as it may help for grading
if (pathname === '/users') {
connection.query('SELECT * FROM userInformation', (err, result) => {
if (err) throw err;
//Return headers
res.writeHead(200, {'Content-Type': 'application/json'});
res.end(JSON.stringify(result));
});
}
// Retrieve a single record by name
else if (pathname.startsWith('/users/')) {
let name = pathname.split('/')[2]
connection.query('SELECT * FROM userInformation WHERE first_name = ?', name, (err, result) => {
if (err) throw err;
res.writeHead(200, {'Content-Type': 'application/json'});
res.end(JSON.stringify(result));
});
}
}
// Handle POST requests , Create part of CRUD
/* EXAMPLE SUBMISSION JSON:
Required Parameters: title , first_name, surname , mobile , email_address, addressLine1, addressLine2 , town, county, eircode
{
"title":"mr",
"first_name":"Greg",
"surname": "Hello",
"mobile" : "12323213",
"email_address":"hello",
"addressLine1": "Someplace",
"addressLine2": "OtherPlace",
"town": "mullingar",
"county": "Westmeath",
"eircode": "NAWD1123"
}
*/
else if (req.method === 'POST') {
// Create a new record
if (pathname === '/users') {
let { headers } = req;
let ctype = headers["content-type"];
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
if(ctype.match(new RegExp('^application/x-www-form-urlencoded'))){
data = querystring.parse(body);
}
else{
data = JSON.parse(body);
}
let user = {
title: data.title,
first_name: data.first_name,
surname: data.surname,
mobile: data.mobile,
email_address: data.email_address,
addressLine1: data.addressLine1,
addressLine2 : data.addressLine2,
town: data.town,
county: data.county,
eircode: data.eircode
};
connection.query('INSERT INTO userInformation SET ?', user, (err, result) => {
if (err) throw err;
res.writeHead(201, {'Content-Type': 'application/json'});
res.end(JSON.stringify(result));
});
});
}
}
// Handle PUT requests, Update part of CRUD
//Fixed issue where it wasnt taking all params
//Send a put request and specify title , email_address and mobile in the json to update
else if (req.method === 'PUT') {
// Update a record by name
if (pathname.startsWith('/users/')) {
let { headers } = req;
let ctype = headers["content-type"];
let name = pathname.split('/')[2];
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
if(ctype.match(new RegExp('^application/x-www-form-urlencoded'))){
data = querystring.parse(body);
}
else{
data = JSON.parse(body);
}
const user = {
title: data.title,
email_address: data.email_address,
mobile: data.mobile
};
connection.query('UPDATE userInformation SET ? WHERE first_name = ?', [user, name], (err, result) => {
if (err) throw err;
res.writeHead(200, {'Content-Type': 'application/json'});
res.end(JSON.stringify(result));
});
});
}
}
// Handle DELETE requests, Delete part of CRUD
//Only takes name as input so far for deletion need to figure out how to make it take the rest of the parameters
else if (req.method === 'DELETE') {
console.log("working");
// Delete a record by ID
if (pathname.startsWith('/users/')) {
const name = pathname.split('/')[2];
console.log("working");
console.log(name);
connection.query('DELETE FROM userInformation WHERE first_name = ?', name, (err, result) => {
if (err) throw err;
res.writeHead(200, {'Content-Type': 'application/json'});
res.end(JSON.stringify(result));
});
}
}
//Make sure to exit out of the server properly else there might be a background process running that will keep using the port which you might have to kill or change the value of the port in the code for it to work again
}).listen(3010, () => {
console.log('Server is listening on port 3010');
});
Client Side:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<title>Document</title>
</head>
<body>
<div class="get">
<h1>Get Data</h1>
<label for="name">Enter Name To Search By:</label><br>
<input type="text" id="name" name="name"><br>
<button id="getDataBtn">Submit</button>
</div>
<div id="userData">
</div>
<div class="post">
<h1>Post Data</h1>
<form id="postData">
<label for="title">Title</label><br>
<input type="radio" id="title" name="title" value="Mr">Mr</input><br>
<input type="radio" id="title" name="title" value="Mrs">Mrs</input><br>
<input type="radio" id="title" name="title" value="Ms">Ms</input><br>
<input type="radio" id="title" name="title" value="Miss">Miss</input><br>
<input type="radio" id="title" name="title" value="Dr">Dr</input><br>
<input type="radio" id="title" name="title" value="Other">Other</input><br>
<label for="first_name">First name:</label><br>
<input type="text" id="first_name" name="first_name"><br>
<label for="surname">Last name:</label><br>
<input type="text" id="surname" name="surname"><br>
<label for="mobile">Mobile:</label><br>
<input type="text" id="mobile" name="mobile"><br>
<label for="email_address">Email:</label><br>
<input type="text" id="email_address" name="email_address"><br>
<label for="addressLine1">Adress Line 1:</label><br>
<input type="text" id="addressLine1" name="addressLine1"><br>
<label for="addressLine2">Adress Line 2:</label><br>
<input type="text" id="addressLine2" name="addressLine2"><br>
<label for="town">Town:</label><br>
<input type="text" id="town" name="town"><br>
<label for="county">County:</label><br>
<input type="text" id="county" name="county"><br>
<label for="eircode">Eircode:</label><br>
<input type="text" id="eircode" name="eircode"><br>
<input type="submit" value="submit">
</form>
</div>
<div class="update">
<h1>Update Data</h1>
<form id="updateData">
<label for="nameUpdate">Enter Name To Update:</label><br>
<input type="text" id="nameUpdate" name="nameUpdate"><br>
<br>
<label for="phone">New Phone Number:</label><br>
<input type="text" id="phone" name="phone"><br>
<label for="email">New Email:</label><br>
<input type="text" id="email" name="email"><br>
<label for="titleUpdate">New Title:</label><br>
<input type="radio" id="titleUpdate" name="titleUpdate" value="Mr">Mr</input><br>
<input type="radio" id="titleUpdate" name="titleUpdate" value="Mrs">Mrs</input><br>
<input type="radio" id="titleUpdate" name="titleUpdate" value="Ms">Ms</input><br>
<input type="radio" id="titleUpdate" name="titleUpdate" value="Miss">Miss</input><br>
<input type="radio" id="titleUpdate" name="titleUpdate" value="Dr">Dr</input><br>
<input type="radio" id="titleUpdate" name="titleUpdate" value="Other">Other</input><br><br>
<input type="submit" value="submit"></button>
</form>
</div>
<div class="delete">
<h1>Delete Data</h1>
<label for="nameDel">Enter Name To Delete By:</label><br>
<input type="text" id="nameDel" name="nameDel"></input><br>
<button id="getDelBtn">Submit</button>
</div>
<div class="watermark"><script src="https://tryhackme.com/badge/119364"></script></div>
</body>
<script>
const getDataBtn = document.getElementById("getDataBtn");
getDataBtn.addEventListener("click", () => {
const name = document.getElementById("name").value;
// GET
fetch(`http://localhost:3010/users/${name}`,{method:"GET"})
.then(response => response.json())
.then(data => {
// Display the retrieved user data on the page
const userData = document.getElementById("userData");
userData.innerHTML = `<h2>User Data</h2> <p>ID: ${data[0].id}</p> <p>Title: ${data[0].title} </p> <p>Name: ${data[0].first_name}</p> <p>Surname: ${data[0].surname}</p> <p>Mobile: ${data[0].mobile}</p> <p>Email: ${data[0].email_address}</p> <p>Address Line 1: ${data[0].addressLine1}</p> <p>Address Line 2: ${data[0].addressLine2}</p> <p>Town: ${data[0].town}</p> <p>County: ${data[0].county}</p> <p>Eircode: ${data[0].eircode}</p>`;
})
.catch(error => console.error(error));
});
//DELETE
const getDelBtn = document.getElementById("getDelBtn");
getDelBtn.addEventListener("click", () => {
const nameDel = document.getElementById("nameDel").value;
// DELETE
console.log(nameDel)
fetch(`http://localhost:3010/users/${nameDel}`,{method:"DELETE",
headers: {
'Content-Type': 'application/json'
}
})
.then(data => {
alert("Successful Delete")
})
.catch(error => console.error(error.message));
});
//POST
//Using Johns template here
$(document).ready(function () {
//Post
$('#postData').submit((e) =>
{
var userData = {
title: $('input[name=title]').val(),
first_name: $('input[name=first_name]').val(),
surname: $('input[name=surname]').val(),
mobile: $('input[name=mobile]').val(),
email_address: $('input[name=email_address]').val(),
addressLine1: $('input[name=addressLine1]').val(),
addressLine2: $('input[name=addressLine2]').val(),
town: $('input[name=town]').val(),
county: $('input[name=county]').val(),
eircode: $('input[name=eircode]').val()
}
$.ajax({
type: 'POST',
url: 'http://localhost:3010/users',
data: userData
}).done((data)=>
{
$('input[name=title]').val('');
$('input[name=first_name]').val('');
$('input[name=surname]').val('');
$('input[name=mobile]').val('');
$('input[name=email_address]').val('');
$('input[name=addressLine1]').val('');
$('input[name=addressLine2]').val('');
$('input[name=town]').val('');
$('input[name=county]').val('');
$('input[name=eircode]').val('');
alert("Successfull Submission");
})
e.preventDefault();
})
//Update
$('#updateData').submit((e) =>
{
var userData2 = {
title: $('input[name=titleUpdate]').val(),
email_address: $('input[name=email]').val(),
mobile: $('input[name=phone]').val()
}
console.log(userData2)
const nameSearch = document.getElementById("nameUpdate").value;
console.log(nameSearch)
$.ajax({
type: 'PUT',
url: `http://localhost:3010/users/${nameSearch}`,
data: userData2
}).done((data)=>
{
$('input[name=titleUpdate]').val('');
$('input[name=phone]').val('');
$('input[name=email]').val('');
alert("Successfull Update");
})
e.preventDefault();
})
});
</script>
</html>
The issue is with the client side delete fetch request.
I have tested the endpoint with thunder client and It works as intended however when I try it through fetch on my front end the request hangs until it timeouts.I don't receive any logs from my server indicating a connection.The get request above it works perfectly and I don't understand why my delete doesn't as they are very similar.