how fix PUT , error 500 id = undefined ReactJs NodeJs - mysql

I would like to explain my problem of the day.
error 500 , id = undefined, no idea why ,
I try to post whatever you may need
how can I fix this issue?
thats is function
handleSubmit = (e, id) => {
e.preventDefault();
const userIdData = { id };
const config = {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({userIdData, livree: new Date().toISOString().slice(11, 16)}),
};
const url = entrypoint + "/alluserpls";
fetch(url, config)
.then(res => res.json())
.then(res => {
if (res.error) {
alert(res.error);
else {
alert(`ajouté avec l'ID ${res}!`);
}
}).catch(e => {
console.error(e);
}).finally(() => this.setState({ redirect: true })); }
my routes
app.put('/api/alluserpls', (req, res, ) => {
const formData = req.body;
const userId = req.body.id;
const deleteQuery = `UPDATE alluserpls SET ? WHERE id = ${userId}`;
connection.query(deleteQuery, err => {
if (err) {
console.log(err)
res.status(500).send("Erreur lors de la modification des users");
} else {
res.sendStatus(200);
}
});
});
my button
<form onSubmit={(e) => this.handleSubmit(e, datass.id)}>
<button type="submit">PUT</button>
</form>
console.log result
errno: 1064,
sqlMessage: "You have an error in your SQL syntax; check the manual that corresponds to
your MariaDB server version for the right syntax to use near '? WHERE id = undefined' at
line 1",
sqlState: '42000',
index: 0,
sql: 'UPDATE alluserpls SET ? WHERE id = undefined'
}
PUT /api/alluserpls 500 14.354 ms - 40

Replace the userId line with this:
const userId = req.body.userIdData.id;
with ES6 Object Destructring:
const { id } = req.body.userIdData
Also, it'll be cleaner if you remove the formData declaration since it's not used in the route handler.

Related

TypeError MySQL: Bind parameters must not contain undefined

So here is the controller's code which I am using to handle password generation process. There is a table called as passwordrecovery which has the following columns:-
id
uuid
email
isActive
Code
File: db.js
const mysql = require("mysql2");
const connectionPool = mysql.createPool({
user: "root",
database: "expensetracker",
host: "localhost",
password: process.env.MYSQL_PASSWORD,
});
module.exports = connectionPool;
File- users.js
const path = require("path");
const db = require("../database/db");
exports.passwordGenerator = async (req, res, next) => {
var id = req.query.id;
console.log(id);
await db.execute(
"SELECT uuid, isActive FROM passwordrecovery WHERE id = ?",
[id],
(err, results) => {
if (err) {
console.log(err);
res.status(500).send("SERVER ERROR");
} else {
//console.log(results);
const response = results[0];
const isActive = parseInt(response.isActive);
if (isActive == 1) {
db.execute(
"UPDATE passwordrecovery SET uuid = ?, isActive = 0 WHERE id = ?",
[null, id],
(err, results) => {
if (err) {
console.log(err);
return res.status(500).send("SERVER ERROR");
} else {
console.log(results);
return res
.status(200)
.sendFile(
path.join(
__dirname,
"..",
"views",
"password-reset-form.html"
)
);
}
}
);
} else {
res.status(408).send("SESSION EXPIRED");
}
}
}
);
};
Error Message
undefined
TypeError: Bind parameters must not contain undefined. To pass SQL NULL specify JS null
at D:\Projects\Expense Tracker\Backend\node_modules\mysql2\lib\connection.js:659:17
at Array.forEach (<anonymous>)
at PoolConnection.execute (D:\Projects\Expense Tracker\Backend\node_modules\mysql2\lib\connection.js:651:22)
at D:\Projects\Expense Tracker\Backend\node_modules\mysql2\lib\pool.js:172:14
at D:\Projects\Expense Tracker\Backend\node_modules\mysql2\lib\pool.js:45:37
at processTicksAndRejections (node:internal/process/task_queues:78:11)
I was expecting that this express js server would return that html(password-reset-form.html) file which it does, here is response from server but it also console logs this error message. I don't know what to, tried my best to resolve myself, read some blogs, googled some stuff but still could not solve this error!

How to send a number to node.js from Angular

I am working on a full stack development using Angular, Node and mySQL. I have to send an index number of a list that the user clicks on an HTML, to a node.js where then, I will have to delete that index row from mySQL. However, I am getting an unusual error. This is my code:
HTML
<tbody *ngFor = "let db of dbData" >
<tr>
<td>{{+db.idoffice + +1}}</td>
<td>{{db.ProjectName}}</td>
<td>{{db.FiscalYear}}</td>
<td>{{db.TaskDescription}}</td>
<td>{{db.ConcernedDepartment}}</td>
<td>{{db.ActivityType}}</td>
<td>{{db.Quarter}}</td>
<td>{{db.kra}}</td>
<td>{{db.CurrentStatus}}</td>
<td>{{db.ResourceName}}</td>
<td>{{db.Notes}}</td>
<td><button class = "btn btn-success nc-icon nc-refresh-69" name="button"></button></td>
<td><button class = "btn btn-danger nc-icon nc-simple-delete" name="button" (click) =
"onDeletePosts(db.idoffice)"></button></td>
</tr>
</tbody>
Angular
private onDeletePosts(delData)
{
this.http.delete('http://localhost:3000/del', delData)
.subscribe(responseData => {
console.log(responseData);
});
}
Node.js
router.delete("/del", (req, res) => {
var del = req.body.delData;
console.log(del);
mysqlConnection.query("DELETE FROM office WHERE idOffice == ?", del , (err, results) => {
if(!err)
{
res.send(results);
}
else
{
console.log("Error occured while deleting" + err.message);
}
})
})
This is the error that I am getting:
undefined //somehow the data from angular to node isn't being received
Error occured while deletingER_PARSE_ERROR: You have an error in your SQL syntax; check the manual
that corresponds to your MySQL server version for the right syntax to use near '== ?' at line 1
Angular HttpClient's delete method does not take a body in it's argument. Instead you could send the ID as an URL query parameter.
Angular
import { HttpClient, HttpParams } from '#angular/common/http';
private onDeletePosts (delData: any) {
const params = new HttpParams().set('id', delData);
this.http.delete('http://localhost:3000/del', { params }).subscribe({
next: responseData => { console.log(responseData); },
error: error => { console.log(error); }
});
}
Node.js
router.delete("/del", (req, res) => {
var id = req.query.id;
console.log(id);
mysqlConnection.query("DELETE FROM office WHERE idOffice == ?", id, (err, results) => {
if (!err) {
res.send(results);
} else {
console.log("Error occured while deleting" + err.message);
}
})
})
It says there's something wrong with the query syntax.
The comparison operator you used is "==". There is no double equal in MySQL, so it's supposed to be "="
Angular
private onDeletePosts(del_id)
{
this.http.delete(`http://localhost:3000/del/${del_id}`)
.subscribe(responseData => {
console.log(responseData);
});
}
node.js
router.delete("/del/:del", (req, res) => {
const { del } = req.params;
console.log(del);
mysqlConnection.query("DELETE FROM office WHERE idOffice == ?", del, (err, results) => {
if (!err) {
res.send(results);
}
else {
console.log("Error occured while deleting" + err.message);
}
})
})

How can I make my Node.js MySQL connection as a promise work?

I have just started to work with node.js and my js knowledge is a bit rusty.
I started with callbacks and then I found out about promises. This syntax was more like my brain works, so I rewrote my code with promises.
But now my MySql connection does not work. It can't even get reached (I think...)
I have logged the word "test" in the file userDB, that worked. But then in the mySql file the console.log "test2" didn't work.
Thanks to you all!
Chris
Here is my server.js (the file that node starts):
/* REQUIRE */
const oAuth2Server = require('node-oauth2-server');
const express = require('express');
const bodyParser = require('body-parser');
const oAuthModel = require('./endpoints/auth/authModel');
const util = require('util');
const dbCon = require('./subsystem/mySql')
/* CONST */
const port = 3000;
const debug = true;
const app = express();
/* INIT */
app.oauth = oAuth2Server({
model: oAuthModel,
grants: ['password'],
debug: debug
})
/* ROUTER */
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(app.oauth.errorHandler());
const authRoutes = require('./router/auth')(express.Router(), app, dbCon)
app.use('/auth', authRoutes);
app.all('*', (req, res) => {
res.status(404).send({message: "This service was not found"});
});
/* Start Server */
app.listen(port, () => {
console.log(`listening on port ${port}`)
})
Here is my router file auth.js:
module.exports = (router, expressApp, dbCon) => {
const userDB = require('../endpoints/user/userDB')(dbCon)
const authMiddleware = require('../endpoints/auth/authMiddleware')
const userMiddleware = require('../endpoints/user/userMiddleware')(userDB)
router.post('/registerUser', userMiddleware.registerUser)
//router.post('/login', expressApp.oauth.grant(), authMiddleware.login)
router.post('/login', expressApp.oauth.grant())
return router
}
Here is my userDB file:
let mySqlConnection;
module.exports = injectedMySqlConnection => {
mySqlConnection = injectedMySqlConnection
return {
registerUserInDB: registerUserInDB,
getUserFromCrentials: getUserFromCrentials,
doesUserExist: doesUserExist,
getUserByUsername: getUserByUsername
}
}
const registerUserInDB = (username, password) => {
return new Promise((resolve,reject) => {
//execute the query to register the user
mySqlConnection.query(`INSERT INTO users (username, user_password) VALUES ('${username}', SHA('${password}'))`)
.then(data => {resolve(true)})
.catch(error => {reject(error)})
})
}
const getUserFromCrentials = (username, password) => {
return new Promise((resolve,reject) => {
//create query using the data in the req.body to register the user in the db
const getUserQuery = `SELECT * FROM users WHERE username = '${username}' AND user_password = SHA('${password}')`
console.log('getUserFromCrentials query is: ', getUserQuery);
//execute the query to get the user
mySqlConnection.query(getUserQuery)
.then(data => {resolve(data)})
.catch(error => {reject(error)})
})
}
const doesUserExist = username => {
return new Promise((resolve,reject) => {
console.log('test');
//execute the query to check if the user exists
mySqlConnection.query(`SELECT * FROM users WHERE username = '${username}'`)
.then(data => {resolve(data.results !== null ? data.results.length == 1 ? true : false : false)})
.catch(error => {reject(error)})
})
}
const getUserByUsername = username => {
return new Promise((resolve,reject) => {
//execute the query to check if the user exists
mySqlConnection.query(`SELECT id, username FROM users WHERE username = '${username}'`)
.then(data => {resolve(data)})
.catch(error => {reject(error)})
})
}
Here is my userMiddleware (is this middleware?):
let userDb;
module.exports = injectedUserDb => {
userDb = injectedUserDb
return {
registerUser: registerUser
}
}
function registerUser(req, res){
console.log(`authRoutesMethods: registerUser: req.body is:`, req.body);
//query db to see if the user exists already
userDb.doesUserExist(req.body.username)
.then(data => {
if(data)
{
sendResponse(res, "User already exists", 200)
return
}
else
{
//register the user in the db
userDb.registerUserInDB(req.body.username, req.body.password)
.then(data => {
userDb.getUserByUsername(req.body.username)
.then(data => {sendResponse(res, data.results, "")})
.catch(error => {sendResponse(res, "Failed to register user", error)})
})
.catch(error => {sendResponse(res, "Failed to register user", error)})
}
})
.catch(err => {
sendResponse(res, "User already exists", 200)
return
})
}
function sendResponse(res, message, error) {
res
.status(error !== null ? error !== null ? 400 : 200 : 400)
.json({
'message': message,
'error': error,
})
}
And last but not least my mySql.js file:
var mySql = require('mysql');
const query = sql => {
return new Promise( ( resolve, reject ) => {
let connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'oauth2test'
});
console.log('test2');
connection.query( sql, ( err, rows ) => {
if ( err )
{
connection.end();
reject( err );
}
else
{
connection.end();
resolve( rows );
}
});
});
}
module.exports.query = query;
You have a simple typo in your mySql.js file:
The line
var mySql = require('mysql');
should be replaced with
var mysql = require('mysql');
Other than that the query code works ok on my machine:
var mysql = require('mysql');
const query = sql => {
return new Promise( ( resolve, reject ) => {
let connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'oauth2test'
});
console.log('test2');
connection.query( sql, ( err, rows ) => {
if ( err )
{
connection.end();
reject( err );
}
else
{
connection.end();
resolve( rows );
}
});
});
}
module.exports.query = query;

Lambda function MySQL result not working on NodeJs 8.10

I have a code in Node 6.10 and it is working...
But If I convert it to Node 8.10 it's not working
var mysql = require("mysql");
var connection = mysql.createConnection({
host: " localhost",
user: "root",
password: "",
database: "parser_db"
});
exports.handler = async event => {
connection.connect();
let response = {
statusCode: 400,
body: { Method: "Invalid", event }
};
var readTable = "SELECT * FROM documents where id = " + mysql.escape(1);
connection.query(readTable, function(err, results, fields) {
if (err) throw err;
else {
response = {
statusCode: 200,
body: { results }
//body: { results }
};
console.log(response);
return response;
}
});
};
Can some one please help me to detect the problem. It is also not working if I do the MySQL query in separate file and return the result set.
Note : If I print the result using console.log(response) instead returning it's
showing the correct result.
The problem is that you are returning response from within the connection.query() callback function. That makes response the return value for the callback function, not the return value for the outer Lambda function.
One way to restructure this code is as follows:
exports.handler = async (event) => {
connection.connect();
return new Promise((resolve, reject) => {
const readTable = `SELECT * FROM documents where id = ${mysql.escape(1)}`;
connection.query(readTable, (err, results, fields) => {
if (err) {
reject(err);
} else {
resolve({statusCode: 200, body: {results}});
}
});
});
};
In addition to #jarmod's answer, You can also use the util.promisify method to promisify connection.query so that you can use the await keyword, to make the code simpler
const util = require('util');
exports.handler = async (event) => {
connection.connect();
const readTable = `SELECT * FROM documents where id = ${mysql.escape(1)}`;
const connQueryPromisified = util.promisify(connection.query).bind(connection);
const result = await connQueryPromisified(readTable);
return {statusCode: 200, body: {results}};
};

How do I pass mysql database content to a different page?

I am trying to display my database content to an ejs web page. However, I am running into a problem when trying to pass the content between pages.
I have a JavaScript page "store.js" which has the server running:
store.js-
var express = require('express');
var dbcon = require('./app/db/databaseconnection');
//var path = require('path');
//dbcon.connection;
var app = express();
var router = express.Router();
dbcon.connect();
console.log(dbcon.getproducts());
//var filepath = path.join(__dirname, '../../views/')
var filepath = __dirname + '/views/';
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/public'));
app.use('/', router);
router.get('/', (request, response) => response.render(filepath + 'index', { page_name: 'home' }));
router.get('/store', (request, response) => response.render(filepath + 'store', { page_name: 'store' }));
router.get('/about', (request, response) => response.render(filepath + 'about', { page_name: 'about' }));
router.get('/contact', (request, response) => response.render(filepath + 'contact', { page_name: 'contact' }));
router.get('/build', (request, response) => response.render(filepath + 'build/build'));
router.get('/learn', (request, response) => response.render(filepath + 'learn/learn'));
app.use('*', (request, response) => response.render(filepath + '404', { page_name: '404' }));
app.listen(3000, () => console.log("Server running at Port 3000"));
Then I have a JavaScript page which includes the database connection:
databaseconnection.js-
var mysql = require('mysql');
var connection = mysql.createConnection(conObject = {
host: "localhost",
user: "root",
password: "LOTOS123l",
database: "dbComputerStore"
});
module.exports = {
connect: () =>
{
connection.connect((error) => {
if (error) throw error;
console.log(conObject.database + " connected!");
});
},
// The display method prints the returned result to the console.
// Change this to return the result. Maybe a toString() ?
getproducts: () => {
/*var result = */connection.query('SELECT * FROM products', (error, result) => {
return result;
//return result;
// console.log(result);
// How to get certain properties
// console.log(result[0].brand);
// console.log(result[0].series);
// console.log(result[0].model);
});
//return result.result;
},
createdb: () => {
},
createtable: () => {
},
populatetable: () => {
}
}
So on the store.js page I have the console.log(dbcon.getproducts()); Which I was hoping would display the database content of the "products" table. However I keep getting undefined. Basically, I can't get it to pass from the database connection page to the store.js page.
If I get this to work, my next step would be to find a way to display the products table to an ejs page. I've been trying to solve this for a while now so any help would be appreciated! Thank You!
Following up my comments, here's how you can modify databaseconnection.js module to use a connection pool and return query results via Promises:
Note: the code is mostly untested
const mysql = require("mysql");
const pool = mysql.createPool({
connectionLimit: 10, // adjust this according to your needs
host: "localhost",
user: "root",
password: "LOTOS123l",
database: "dbComputerStore"
});
module.exports = {
// you don't need the connect method anymore
getProducts: () => new Promise((resolve, reject) => {
pool.query("SELECT * FROM products", (error, results, fields) => {
if (error) {
reject(error);
} else {
resolve(results);
}
});
}),
// ...
};
then in store.js, you can do:
const dbcon = require('./app/db/databaseconnection');
dbcon.getProducts()
.then(results => {
console.log(results);
})
.catch(err => {
console.error(err);
});
// or you could use async/await syntax:
const asyncFn = async () => {
try {
const results = await dbcon.getProducts();
console.log(results);
} catch (ex) {
console.error(err);
}
};
asyncFn();