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;
}
Related
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 want to click a button to display API data using JavaScript Fetch but I'm getting trouble with TypeError: NetworkError when attempting to fetch resource.
I think it has to do with the HTML form. If someone can help me with this. I'm trying to fetch data from NASA APIs.
The JS Code is below
var search = document.getElementById("search");
search.addEventListener("click",function(){
//var startdate = document.getElementById("starter");
//var enddate = document.getElementById("enddate");
var url = "https://api.nasa.gov/planetary/apod?api_key=key";
fetch(url,{
method:"GET",
headers:{
"Content-Type":"application/json"
},
mode:"cors",
catch:"default"
}).then(function(response){
if(response.ok){
return response.json();
}else{
throw new Error(Error);
}
}).then(function(data){
console.log(data);
}).catch(function(error){
console.log(error);
});
});
Below is the HTML form
<form>
<input type="date" id="startdate" placeholder="enter a start date"><br>
<input type="date" id="enddate" placeholder="enter a start date"><br>
<button type="submit" id="search">Search</button>
</form>
Thanks
Try this, I have added event.preventDefault() this will prevent the page from refreshing. Also do not forget to use the proper API key provided by the service provider.
var search = document.getElementById("search");
search.addEventListener("click",function(event){
event.preventDefault();
//var startdate = document.getElementById("starter");
//var enddate = document.getElementById("enddate");
var url = "https://api.nasa.gov/planetary/apod?api_key=key";
fetch(url,{
method:"GET",
headers:{
"Content-Type":"application/json"
},
mode:"cors",
catch:"default"
}).then(function(response){
if(response.ok){
return response.json();
}else{
throw new Error(Error);
}
}).then(function(data){
console.log(data);
}).catch(function(error){
console.log(error);
});
});
You don't need options for your fetch request,
Also you need to prevent the page from reload
Here is a full working example
var search = document.getElementById("search");
search.addEventListener("click", function(e) {
e.preventDefault();
fetch("https://api.nasa.gov/planetary/apod?api_key=key_obtained_from_nasa")
.then(function(response) {
if (response.ok) {
return response.json();
}
throw new Error();
}).then(result => console.log(result))
.catch(function(response) {
console.log('Error! Please try again');
});
})
<form>
<input type="date" id="startdate" placeholder="enter a start date"><br>
<input type="date" id="enddate" placeholder="enter a start date"><br>
<button type="submit" id="search">Search</button>
</form>
Hello I have a little problem with my project which uses the Microsoft Graph API. I need to implement a REST API that retrieves users' shared calendar from an Azure AD. I use NodeJS and express for this.
Here is the handlebars:
enter image description here
I implemented a script (script.js) which retrieves the username of the users (the username corresponds to their email address):
enter image description here
Now that I get the email address of the person I want to consult his calendar I would have to pass this variable in a function of another script (graph.js):
enter image description here
I would like instead of the giveUser () function in the getSharedCalend to put the email address of the person who has been checked in the .hbs
Thank you in advance for your help.
Ok, I spent a few minutes reading this over and over and I probably got this.
You have two scripts. script.js which is a client side script and graph.js which is a server side script.
Those scripts cannot communicate directly. script.js is running in the user browser and graph.js is running at your server. What you can do is make HTTP request. Either by creating html <form> or by JavaScript using fetch. Then you can redirect user to the calendar.
calendar.hbs :
<table class="table">
<thead>
<tr>
<th scope="col">Organizer</th>
<th scope="col">Subject</th>
<th scope="col">Start</th>
<th scope="col">End</th>
</tr>
</thead>
<tbody>
{{#each shrdcalend}}
<tr>
<td>{{this.organizer.emailAddress.name}}</td>
<td>{{this.subject}}</td>
<td>{{eventDateTime this.start.dateTime}}</td>
<td>{{eventDateTime this.end.dateTime}}</td>
</tr>
{{/each}}
</tbody>
</table>
<h1>Choice Shared Calendar</h1>
<table class="table">
<thead>
<tr>
<th scope="col">nom</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<form id="inscription">
{{#each usersprop}}
{{this.userPrincipalName}} : <input type="radio" name="username" id="username" value={{this.userPrincipalName}}><br>
{{/each}}
<td> <button type ="submit" value="inscription" >Voir Calendrier</button> </td>
</form>
<p style ="color: red;"id="erreur"></p>
</td>
</tr>
</tbody>
</table>`
//script on calendar.hbs
`<script>
document.getElementById("inscription").addEventListener("submit",function(e){
var erreur;
var entrer = document.getElementById("inscription").getElementsByTagName("input");
console.log(entrer);
for (var i=0 ; i<entrer.length; i++ ){
var chek = entrer[i].checked;
var username = entrer[i].value;
if(chek == true){
console.log(chek);
console.log(e);
console.log(username);
alert(username);
alert('formulaire envoyé !');
return username;
}else{
erreur = "0 case selec";
}
}
if(erreur){
e.preventDefault();
document.getElementById("erreur").innerHTML = erreur;
return false;
}
}
);
</script>`
graph.js:var graph = require('#microsoft/microsoft-graph-client');
require('isomorphic-fetch');
module.exports = {
getUserDetails: async function(accessToken) {
const client = getAuthenticatedClient(accessToken);
const user = await client.api('/me').get();
return user;
},
getEvents: async function(accessToken) {
const client = getAuthenticatedClient(accessToken);
const events = await client
.api('/me/calendar/events')
.select('subject,organizer,start,end')
.orderby('createdDateTime DESC')
.get();
return events;
},
getUserS: async function(accessToken) {
const client = getAuthenticatedClient(accessToken);
const usersprop = await client.api('/users').select('userPrincipalName').get();
return usersprop;
},
getSharedCalend: async function(accessToken) {
const client = getAuthenticatedClient(accessToken);
console.log(getusershrd());
const shrdcalend = await client
.api('/users/'+***???***+'/calendar/events')
.get();
return shrdcalend;
}
};
function getAuthenticatedClient(accessToken) {
// Initialize Graph client
const client = graph.Client.init({
// Use the provided access token to authenticate
// requests
authProvider: (done) => {
done(null, accessToken);
}
});
return client;
}`
my file router calendar.js:
var express = require('express');
var router = express.Router();
var tokens = require('../tokens.js');
var graph = require('../graph.js');
/* GET /calendar */
// <GetRouteSnippet>
router.get('/',
async function(req, res) {
if (!req.isAuthenticated()) {
// Redirect unauthenticated requests to home page
res.redirect('/')
} else {
let params = {
active: { calendar: true }
};
// Get the access token
var accessToken;
try {
accessToken = await tokens.getAccessToken(req);
} catch (err) {
req.flash('error_msg', {
message: 'Could not get access token. Try signing out and signing in again.',
debug: JSON.stringify(err)
});
}
if (accessToken && accessToken.length > 0) {
try {
// Get the events
var events = await graph.getEvents(accessToken);
params.events = events.value;
} catch (err) {
req.flash('error_msg', {
message: 'Could not fetch events',
debug: JSON.stringify(err)
});
}
try {
// Get the calendars users
var shrdcalend = await graph.getSharedCalend(accessToken);
params.shrdcalend = shrdcalend.value;
} catch (err) {
req.flash('error_msg', {
message: 'Could not fetch shared calend',
debug: JSON.stringify(err)
});
}
try {
// Get the events
var usersprop = await graph.getUserS(accessToken);
params.usersprop = usersprop.value;
} catch (err) {
req.flash('error_msg', {
message: 'Could not fetch shared calend',
debug: JSON.stringify(err)
});
}
} else {
req.flash('error_msg', 'Could not get an access token');
}
res.render('calendar', params);
}
}
);
module.exports = router;
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.
I am able to successfully retrieve a document in Firebase Firestore in JavaScript. But would like to validate that document against a user's entry in order to auth that individual into the page.
Using console log I see that I have retrieved the record but it is not matching it against the text inputted by the end user.
How is this accomplished?
I am using Vuejs. And want to password protect one page.
In jsfiddle: https://jsfiddle.net/oL4bondy/4/
HTML
<div v-if="!isLoggedIn">
<h2>Please log in first.</h2>
<div class="form-group">
<form #submit.prevent="validatePin">
<div class="form-group">
<input v-model="password" type="text" class="form-control" placeholder="Enter password">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary text-center">Submit</button>
</div>
</form>
</div>
</div>
JS
export default {
name: "add-post",
data() {
return {
password: "",
isLoggedIn: ""
};
},
methods: {
validatePin() {
const docRef = db.collection("passwords").doc("user");
docRef
.get()
.then(function(doc) {
if (doc.exists) {
console.log("Document data:", doc.data());
} else {
console.log("No such document!");
}
})
.catch(function(error) {
console.log("Error getting document:", error);
});
let password = this.doc.data;
if (this.userInput === password) {
this.isLoggedIn = true;
}
}
}
};
Use Firebase.auth() for this. In particular, the .onAuthStateChanged method/listener will fire after page load. That's where you want to process user/UI access.
There are a few problems, but mostly it's related to the fact that the document is loaded from Firestore asynchronously. The solution is to move all the code that needs the document into the then() that is called once the document is loaded. So:
validatePin() {
const docRef = db.collection("passwords").doc("user");
docRef
.get()
.then(function(doc) {
if (doc.exists) {
console.log("Document data:", doc.data());
let password = this.doc.data;
if (this.userInput === password) {
this.isLoggedIn = true;
// TODO: do whatever needs to happen once the user is logged in
}
} else {
console.log("No such document!");
}
})
.catch(function(error) {
console.log("Error getting document:", error);
});
}