If I have some HTML code:
<div>
<input type="text" name="user" placeholder="User Name" />
<input type="password" name="password" placeholder="Password" />
<button type="button">Login</button>
</div>
and when I click on the login button, it goes to the /api/users/ function in my nodejs file. How do I pass the strings stored in the username and password in the HTML code? Using sqlite3.
app.get('/api/users/', function (req, res) {
let sql = 'SELECT * FROM users;';
db.all(sql, [], (err, rows) => {
var result = {};
result["users"] = [];
if (err) {
result["error"] = err.message;
}else {
rows.forEach((row) => {
result["users"].push(row);
});
}
res.json(result);
});
});
I want to execute some type of function, where if the username and password does not exist, than add it to the table "users" and redirect to another HTML file.
You should use a html form. See here. You're HTML is just sending an empty get request to your API, a form will send the data as well.
Related
I'm working on an application using nodejs, mysql and express currently and I have run into an issue with fetching data from my database.
I have a POST form in the client side for booking and I want to implement a feature for the client to only be able to see non-booked times for the date which they have selected. But the problem is that once they select a date the request gets stuck in pending.
ps. this is a school project so i'm very new to nodejs and programming any help would be greatly appreciated
Heres my router.js file:
const express = require('express');
const router = express.Router();
const pool = require('../config/database.js')
router.get('/', (req, res) => {
res.render('home.ejs');
});
router.get('/book', function(req, res){
res.render('book.ejs')
});
router.get('/book/:date', function(req, res) {
const date = req.params.date;
console.log('Start of route handler');
// Fetch all bookings for the given date
pool.query('SELECT time FROM bookings WHERE date = ?', [date], function(err, bookings) {
if (err) {
console.error(err);
return res.status(500).send({ error: 'Something went wrong on the server' });
}
console.log('SQL query success');
// Get all available times for the given date
try {
const availableTimes = getAvailableTimes(date, bookings);
console.log('Successfully retrieved available times');
res.json(availableTimes);
} catch (error) {
console.error(error);
res.status(500).send({ error: 'Something went wrong on the server' });
}
});
});
// Function to get all available times for a given date
function getAvailableTimes(date, bookings) {
const allTimes = ['09:00:00', '10:00:00', '11:00:00', '12:00:00', '13:00:00', '14:00:00', '15:00:00', '16:00:00', '17:00:00', '18:00:00'];
const bookedTimes = bookings.map(function(booking) {
return booking.time;
});
const availableTimes = allTimes.filter(function(time) {
return !bookedTimes.includes(time);
});
return availableTimes;
}
module.exports = router;
client-side file:
<!DOCTYPE html>
<html lang="en">
<%- include("./partial/head.ejs"); -%>
<body>
<%- include("./partial/header.ejs"); -%>
<h1 id="bookHeader">Book an Appointment</h1>
<form method="post" action="/Bokning" class="bookForm">
<div class="bookFirstForm">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required />
<label for="email">Email:</label>
<input type="email" id="email" name="email" required />
<label for="phone">Phone:</label>
<input type="text" id="phone" name="phone" required />
</div>
<div class="bookSecondForm">
<label for="tjänst">Tjänst:</label>
<select name="tjänst" id="tjänst">
<option value="Klippning">Klippning</option>
<option value="Skägg">Skägg</option>
<option value="Behandling">Behandling</option>
</select>
<label for="barber">barber:</label>
<select name="barber" id="barber">
<option value="Mushtaq">Mushtaq</option>
<option value="Viggo">Viggo</option>
<option value="Kacper">Kacper</option>
</select>
</div>
<div class="bookThirdForm">
<label for="date">Datum:</label>
<input type="date" id="date" name="date" required />
<label for="time">Tid:</label>
<select id="time" name="time">
</select>
</div>
<button type="submit">Boka Nu!</button>
</form>
<%- include("./partial/footer.ejs"); -%>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
const dateInput = document.getElementById('date');
const timeInput = document.getElementById('time');
// Listen for changes to the date input
dateInput.addEventListener('change', function() {
// Get the selected date
const selectedDate = this.value;
// Make an API call to the server to fetch the booked times for the selected date
fetch(`/book/${selectedDate}`)
.then(response => response.json())
.then(availableTimes => {
// Clear the time input
timeInput.innerHTML = '';
// Populate the time input with the available times
availableTimes.forEach(function(time) {
const option = document.createElement('option');
option.value = time;
option.textContent = time;
timeInput.appendChild(option);
});
})
.catch(error => console.error(error));
});
</script>
</body>
</html>
I have tried putting console logs in my code but I get nothing in response
I think you miss the async and await in your code
router.get('/book/:date', async function(req, res) { // MAKE async CALLBACK
const date = req.params.date;
console.log('Start of route handler');
// Fetch all bookings for the given date
pool.query('SELECT time FROM bookings WHERE date = ?', [date], async function(err, bookings) { // MAKE async CALLBACK
if (err) {
console.error(err);
return res.status(500).send({ error: 'Something went wrong on the server' });
}
console.log('SQL query success');
// Get all available times for the given date
try {
const availableTimes = await getAvailableTimes(date, bookings);
console.log('Successfully retrieved available times');
res.json(availableTimes);
} catch (error) {
console.error(error);
res.status(500).send({ error: 'Something went wrong on the server' });
}
});
});
// Function to get all available times for a given date
async function getAvailableTimes(date, bookings) {
const allTimes = ['09:00:00', '10:00:00', '11:00:00', '12:00:00', '13:00:00', '14:00:00', '15:00:00', '16:00:00', '17:00:00', '18:00:00'];
const bookedTimes = bookings.map(function(booking) {
return booking.time;
});
const availableTimes = allTimes.filter(function(time) {
return !bookedTimes.includes(time);
});
return availableTimes;
}
so i wrote this code and I am getting no errors in the console
the only error i get from the fauna server is An error occurred while logging in.
also i will change the secret key after this is awnsered for security reasons.
const client = new faunadb.Client({
secret: "fnAE7vAmHdAA1I7LvovMRWnGVVM2_sit_IrKDgnN"
});
async function signUp() {
const email = document.getElementById("email").value;
const password = document.getElementById("password").value;
try {
const result = await client.query(
q.Create(
q.Collection("users"),
{
data: {
email,
password
}
}
)
);
alert("Sign up successful! You can now log in.");
} catch (error) {
console.error(error);
alert("An error occurred while signing up.");
}
}
async function login() {
const email = document.getElementById("email").value;
const password = document.getElementById("password").value;
try {
const result = await client.query(
q.Get(
q.Match(
q.Index("users_by_email"),
email
)
)
);
if (result.password === password) {
alert("Login successful!");
} else {
alert("Incorrect email or password.");
}
} catch (error) {
console.error(error);
alert("An error occurred while logging in.");
}
}
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/faunadb"></script>
<script></script>
</head>
<body>
<h1>Sign Up</h1>
<form>
<label for="email">Email:</label>
<input type="email" id="email" required>
<br><br>
<label for="password">Password:</label>
<input type="password" id="password" required>
<br><br>
<button type="button" onclick="signUp()">Sign Up</button>
</form>
<h1>Login</h1>
<form>
<label for="email">Email:</label>
<input type="email" id="email" required>
<br><br>
<label for="password">Password:</label>
<input type="password" id="password" required>
<br><br>
<button type="button" onclick="login()">Login</button>
</form>
</body>
</html>
I've tried looking for errors in thr java script and tried playing around
with the fauna database itself
IMPORTANT
note about credentials in Fauna: using Fauna's built in Credentials support means you don't store the actual password, only the hashed password. This is also what enables Fauna's built in Login function, which returns a new user Token. Your current application provides all users with permissions to read every user, including every user's password, and that is very, very bad.
Your errors
I see that you are trying to access the password field by doing result.password. Notice that when you created the document, password is under the data field.
if (result.data.password === password) {
alert("Login successful!");
} else {
alert("Incorrect email or password.");
}
A better way
You should follow along with the User Authentication Tutorial.
It is my recommendation that you turn signup and login into UDFs and use a public key that has two permissions (and only two permissions):
call Function("signup")
call Function("login")
Then your application can use the public key to access these functions. The login function then gives you a separate Token, which you use to make a new Fauna Client. That Token should have whatever privileges a user should have (but no more).
Fauna Community Resources
Forums: https://forums.fauna.com/
Discord: https://discord.gg/2qXynEjn
i'm working on my very first app : a login/register form with JS/node Js/ Mysql.
I'm trying to connect my form to my database (to collect my users' data into my db) but my code is not working. I didn't use "handleChange" or "onSubmit" functions because i don't use ReactJS framework. Do you guy think it's necessary?
this is my code :
HTML code:
<div class="msg-alerte">message</div>
<form method="post" action="http://localhost:8000/">
<div class="formulaire">
<h1 class="entete">inscription</h1>
<input type="name" placeholder="nom" name="nom" id="nom" autocomplete="off" required>
<input type="email" placeholder="email" name="email" id="email" autocomplete="off" required>
<input type="password" placeholder="mot de passe" name="password" id="password" autocomplete="off" required>
<button class="btn-valider">s'inscrire</button>
Vous avez déjà un compte? Se connecter
</div>
</form>
JS (frontend) :
const username = document.getElementById('name')|| null;
const email = document.getElementById('email');
const password = document.getElementById('password');
const submitBtn = document.querySelector('.btn-valider');
if(username === 0){
}
else{
submitBtn.addEventListener('click', ()=>{
//register-user??
fetch('/', {
method: "post",
headers: new Headers({'Content-Type':'application/json'}),
body: JSON.stringify({
user_name: username,
email: email,
password: password
})
})
console.log(username);
console.log(email);
console.log(password)
.then(res =>res.json())
})
}
js server :
app.post("/",(req,resp)=>{
//insertion d'une donnée
const data={user_name:req.body.user_name,email:req.body.email, password:req.body.password};
let sql="INSERT INTO users (user_name, email, password) VALUES (?,?, ?);";
pool.query(sql,[data],(err,fields)=>{
if(err)console.log("Echec d'enregistrement à BD");
else{
console.log("Enregistrement effectuee");
resp.redirect("/");
}
});
});
THANK YOU FOR YOUR HELP!!!
It looks like the main issue you will want to resolve before you can move forward is with your fetch call in your frontend code. You need to use the then() method on fetch so you can properly parse and read the response. Currently, you are calling .then(res =>res.json()) on a console.log(). This is not valid.
I have made a modification to your event listener function that you can try
submitBtn.addEventListener('click', () => {
fetch('/', {
method: "post",
headers: new Headers({'Content-Type':'application/json'}),
body: JSON.stringify({
user_name: username,
email: email,
password: password
})
})
.then((res) => res.json())
.then((data) => {
// now we can read the response and decide what to do next
console.log(data);
});
})
I'm also seeing some possible syntactical issues in your node js code. Specifically with the request data assignment and the string interpolation on your query string. You could try something like this:
app.post("/", (req, resp) => {
//insertion d'une donnée
const data =[req.body.user_name, req.body.email, req.body.password];
let sql="INSERT INTO users (user_name, email, password) VALUES ($1, $2, $3)";
pool.query(sql, data, (err, fields) => {
if (err) console.log("Echec d'enregistrement à BD");
else {
console.log("Enregistrement effectuee");
resp.redirect("/");
}
});
});
Please comment if you need any further clarification.
I'm building an express.js application that just takes data from A mysql database and displays on the screen and I'm trying too implement an insert functionality so I can add too the database via browser, when I post the results too one of the route points I am returned empty braces and do not know why,any help at all would be appreciated.
Index.js below this is addCountries.ejs
//brings you too add Country
app.get("/addCountries", (req, res) => {
res.render("addCountries")
console.log("hello")
})
//inserts data from add countries
app.post("/addCountries", (req, res) => {
sqlDAO.addCountry()
.then((data) => {
res.render("addCountries", {
addCountries: data
})
console.log(req.body.co_name)
console.log("hello")
})
.catch((error) => {
res.send(error)
console.log("hello")
})
})
<h1>Add Country</h1>
<br>
<br>
<form action="/addCountries" method="POST">
<label for="cCode">Country Code:</label>
<input type="text" id="cCode" name="co_code"><br><br>
<label for="cName">Country Name:</label>
<input type="text" id="cName" name="co_name"><br><br>
<label for="CDetails">Country Details:</label>
<textarea type="text" id="CDetails" name="co_details"></textarea>
<input type="submit" value="Add">
</form>
SQLDAO.js
var pool
//creates pool based on database provided by project spec
mysql.createPool({
connectionLimit: 3,
host: 'localhost',
user: 'root',
password: 'password',
database: 'geography'
})
.then((result) => {
pool = result
})
.catch((error) => {
console.log(error)
})
var addCountry = function() {
// returns new promise
return new Promise((resolve, reject) => {
// function that adds too database
var myQuery = {
sql: "INSERT INTO country VALUES (?, ?, ?)",
values: [req.body.co_code, req.body.co_name, req.body.co_details]
}
pool.query(myQuery)
.then((data) => {
resolve(data)
console.log(data)
})
.catch(error => {
reject(error)
})
})
}
You will need to pass a reference to the request object to addCountry(). This is because the addCountry() function inside the SQLDAO.js file does not have access to the request object.
Right now, in addCountry() the req variable is undefined, so when the SQL statement is compiled there is no data to insert. If you look in the DB you'll likely see empty or no records being added.
By passing in the request object, it has data to place into the db and that the db can return.
Edit both files like this:
sqlDAO.addCountry(req)... then var addCountry = function(req) {...
There are two reasons this is necessary:
Inside your app.post() function both req and res are scoped locally to the function and are unavailable outside that function.
Even if they were pseudo-global, variables are only available within the module they are created within. So you must export that variable or, in this case, pass a reference to it to some other function within some other module.
i'm trying to return one specific user's data from using GET method on Express.js by using Form. But when using form, it's returning all the values.
this is the index.html code :
<form action="http://localhost:1234/users" method="get">
id <input type="number" name="id" placeholder="enter id" /><br/>
</form>
and the app.js code :
app.get('/users/:id', (request, response) => {
const id = request.params.id;
pool.query(`SELECT * FROM users WHERE id = ${id}`, id, (error, result) => {
if (error) throw error;
response.send(result);
});
});
basically when i'm sending request through the url http://localhost:1234/users/1 then, only the specified user's data is shown. But when I'm using form to send the data, what I saw the main problem was the url, now the url becomes like that http://localhost:1234/users?id=1 . For this reason, it's returning all the values from database. How can I solve this? I know maybe, it's a easy one, but as new to node.js and express, I've tried several methods but on form it's not working.
The most natural solution would be to use Ajax to send a query on form submit, and to disable default behaviour of the form (<event>.preventDefault()).
I will tackle a more hacky way that doesn't involve modifying the client, but only the server:
Make :id an optional parameter by adding a question mark
Handling both cases: if req.params.id is defined but req.query.id isn't, or if req.query.id is defined but req.params.id isn't.
app.get('/users/:id?', (request, response) => {
const paramId = request.params.id;
const queryId = request.query.id;
var id;
if(paramId && !queryId)
id = paramId;
else if(queryId && !paramId)
id = queryId;
if(!id)
return response.send('Please specify an id');
pool.query(`SELECT * FROM users WHERE id = ${id}`, id, (error, result) => {
if (error) throw error;
response.send(result);
});
});
With this, the following URLS are fine:
http://localhost:1234/users/1
http://localhost:1234/users?id=1
Those aren't:
http://localhost:1234/users/
http://localhost:1234/users/1?id=1