mysql function does not work in react after several excution - mysql

here is node.js code
var _num;
app.post("/api/get", (req, res) => {
_num = req.body.passNum;
console.log(_num + "insert");
callDb();
});
var callDb = () => {
app.get
("/api/get", (req, res) => {
var sqlSelect = "SELECT * FROM day" + _num;
console.log(_num + "outcome");
db.query(sqlSelect, (err, result) => {
res.send(result);
});
});
};
What is this code? : this code get a number from frontend(react) by click url (from day1 to day3) and it passes into var _num inside backend.
and function callDb gets the var _num, and add in to mysql query, so in conclusion, callDb calls different table from mysql(from day1 to day3).
what is problem? : The first few times work normally, and when clicked several times it doesn't work normally. as you see in my code, to check whether it is working properly, I added console.log (insert and outcome). as callDb inside app.post, after _num gets number from react, callDb has to be start.
so the sequence is, click day1 url->_num gets value"1" and console.log insert comes out(1 insert)->callDb SELECT day1 and console.log outcome comes out (1 outcome).
and after repeat click and go back to main page, the log is
1insert
1outcome
2insert
2outcome
3insert
3outcome
1insert
1outcome
2insert
2outcome
3insert
so from the six time, it makes problem. Only appears insert and after click, there is no log change. which means SELECT did not worked. and after refresh page, consolelog outcome gives proper outcome. so every 6click, user requires refresh.
I'm really confused because it works several times, and at some point it brakes. what is the problem and how can I fix?

app.post("/api/get", (req, res) => {
if(req.body.passNum){//first check if the required parameter is provided
_num = req.body.passNum; //get the parameter. You need to use 'escape string' to escape other dangerous characters which may lead to sql imjection.
db.query("SELECT * FROM day" + _num, (err, result) => {
if (err) {
console.log(err);
res.end("An error occcured while reading from the database");
} else {
res.send(result);
}
});
}else{
res.end("required fields are not provided");
}
});

Related

Having multiple get routes on a NodeJS / Express REST API?

I'm creating a JS web app using NodeJS and Express (with SQL/MySQL for the database), pretty much directly implementing this API tutorial: https://www.bezkoder.com/node-js-rest-api-express-mysql/ (just replacing 'tutorials' with 'Employees').
I'm trying to write API functions to get all Employees with certain attributes (in the SQL table), for example all employees with lastName = "Garcia" or all employees with teamID = 43682, etc.
In my routes.js file I have this:
module.exports = app => {
const employees = require("../controllers/employee.controller.js");
const router = require("express").Router();
// Create a new Employee
router.post("/", employees.create);
// Retrieve all Employees
router.get("/", employees.findAll);
// Retrieve all Employees with lastName
router.get('/', employees.findLastName);
... a bunch more CRUD functions ...
app.use('/api/employees', router);
};
And this is the corresponding Controller function:
exports.findLastName = (req, res) => {
const lastName = req.query.lastName; // tried changing req.query.lastName to req.params.lastName
Employee.getLastName(lastName, (err, data) => {
if (err)
res.status(500).send({
message:
err.message || "Error occurred while retrieving by last name."
});
else {
console.log(`Employees with lastName ${lastName} were found!` );
res.send(data);
}
});
};
exports.findAll = (req, res) => {
const title = req.query.title;
Employee.getAll(title, (err, data) => {
if (err)
res.status(500).send({
message:
err.message || "Some error occurred while retrieving employees."
});
else {
console.log(`Employee with ${title} title was found!` );
res.send(data);
}
});
};
The findAll route/function (just copied from that tutorial) works by finding all Employees with a certain ID number (the primary key in the DB) and I know that works from testing it through Postman. I wrote the findLastName route/function by copying the findAll function and changing it to search by lastName, and making the corresponding functions in the model and controller classes.
The new function, findLastName, doesn't work... unless I put the route before the findAll route (or comment it out). Then it correctly calls all my functions and returns all employees with the lastName param.
What's actually happening here? Are you not allowed to have multiple .get() routes or something? If so, how would I implement a search API like this? This is my first time building a web app like this so admittedly I'm still a little hazy on how routing and all that works. Thank you for any help though!
In Express whenever the first route matches second will be ignored, so in your scenario you have two route.get with same path /
router.get('/', employees.findAll);
//Since route with path `/` is matched above already this will be ignored
router.get('/', properties.findLastName);
In order to find Employees with last name you will need to create a new route with param (param will contain the last name)
router.get('/:lastName', properties.findLastName);
You can access the param value like this req.params.lastName in controller

Next.js MySQL INSERT/UPDATE query never seems to execute

Quite the odd issue here.. I think this may be more of a problem of debugging, however I'm going to post in-case it is truly an issue and I'm quite frankly at my wits end anyway. I am doing a basic React.js/next.js form that takes a few inputs and adds them to state, then using axios sends the update to the api, which then makes a query insert or update to MySQL. The problem is, this Insert/Update doesn't work and I can't get any error output besides generic ETIMEDOUT from time to time, which I'm not even sure are related. I had this fixed before but am still unsure what I did. ALL other queries on the site work fine, the connection to the MySQL (AWS RDS) database is just fine.
My theories are A) the final query syntax has a silly issue causing this to just get lost in the abyss, or B) there's some server side code trying be run client side that I don't quite understand. (have also gotten the module 'fs' not found), or C) an async issue that I am not weathered enough in next.js to fix. And before you say it, yes there is data to be updated in the table, it is not trying to update the same data and thus bypassing the update. It is new data, every time I test.
NOTE-- I should also say, this code works PERFECT on my local osx environment. This ONLY happens when I try to run this on my Vercel deployment environment. This is important to know. The Database and Code are the EXACT same between both environments.
Without further ado, some code:
To save code display, lets assume our values are in state and ready to go to the API, as I know for a fact they are, and they make it to the actual query.
handleSubmit - gets run when the form is submitted.
const handleSubmit = (e) => {
e.preventDefault();
// Loop data, create a list of IDs for the Delete and an
// array of array of arrays for the insert.
let segmentItemIDList = [];
const segmentItemArray = [];
originalSegmentItemList = originalSegmentItemList.join(',')
segmentItemState.map((val, idx) => (
segmentItemArray[idx] = [
segmentItemState[idx].segmentID,
Number(segmentItemState[idx].chronologicalOrder),
Number(segmentItemState[idx].releaseOrder),
segmentItemState[idx].name,
segmentItemState[idx].typeID
]
))
let action = 'updatesegmentitem'
axios.post('/api/list', { action, segmentItemArray })
.then((result) => {
action = 'deletesegmentitem'
axios.post('/api/list', { action, originalSegmentItemList })
.then((result) => {
alert("Updated!!");
})
.catch(error => console.error('Error:', error));
})
.catch(error => console.error('Error:', error));
}
api/list (assume it gets into this block, because it does)
else if(req.body.action == 'updatesegmentitem') {
console.log("2. API updatesegmentitem req.body: ", req.body);
const segmentItemArray = req.body.segmentItemArray;
console.log("SegmentItemArray: ", segmentItemArray);
try {
if(Array.isArray(segmentItemArray) && segmentItemArray.length > 0) {
console.log("Inside IsArray: ", segmentItemArray);
const segmentItemInsertResults = await insertBatchSegmentItems(segmentItemArray);
res.send(segmentItemInsertResults);
} else {
res.send(true);
}
} catch (e) {
res.send('error');
}
insertBatchSegmentItems (mysql query) .. Sometimes I get the console logs in here, sometimes not..
export async function insertBatchSegmentItems(segmentItemData) {
let mysqlConnection = mysql.createConnection({
host: process.env.MYSQL_HOST,
database: process.env.MYSQL_DATABASE,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
debug: false,
});
mysqlConnection.connect();
const insertSQL = 'INSERT INTO segmentItem (segmentID, chronologicalOrder, releaseOrder, name, typeID) VALUES ?'
try {
await mysqlConnection.query(insertSQL, [segmentItemData], function(err, result) {
console.log("Connex Query Inside Result: ", result);
if (err) throw err;
//mysqlConnection.destroy();
return result;
});
} catch (e) {
console.log("ERROR: ", e);
//mysqlConnection.destroy();
return e;
}
return true;
}
Please excuse my mess, I have been trying so many different things to try and get this to work but it will be cleaned up after a solution has been found.
Whenever I run into similar situations, I usually drop out exception handling and let it fail hard. It might give you a better insight of where it's happening. Good luck!

Data not getting change in node js

I am working with Angular, Node and MySQL. I have a simple crud app in which I am adding,updating some data. Whenever I am adding/updating any data I want it to reflect changes in list grid as well.
I am using popups for add/update. So after adding or updating I am calling my generic function which gives me list of data but I was getting response 304 and changes not displayed in grid. So to overcome 304 I have use app.disable('etag') in Node.js which gives me status 200. But still changes not displayed, but when I refresh page manually I can see the changes.
Also when I am checking data in network just after performing operation it also holds old values.
Node.js
app.post("/addcity", function(req, res) {
d = req.body;
var con = mysql.createConnection(connectionString);
con.connect(function(err) {
if (err)
throw err;
var sql = "INSERT INTO tbl_city(city_name,state_id) VALUES('" + d.city_name + "'," + d.state_id + ")";
console.log(sql);
con.query(sql, function(err, result) {
if (err)
throw err;
res.send(result);
})
})
})
Angular code
PostData(addNewForm: NgForm) {
var object = {
"city_name": addNewForm.value.city_name,
"state_id": addNewForm.value.state_id
}
this.service.addCity(object).subscribe();
this.modalRef.hide();
this.getAllCities(); // this still gives old values even new City is added in database
}
Update
getCities() : Observable<any[]>{
var details = this.http.get(`${this.apiUrl}/cities`);
return forkJoin([details]);
}
You are calling the two requests in async, that's why by the time the city is added in database. this.getAllCities() gets the list of old cities try it like this.
PostData(addNewForm: NgForm) {
var object = {
"city_name": addNewForm.value.city_name,
"state_id": addNewForm.value.state_id
}
this.service.addCity(object).subscribe(
(data)=> {
this.modalRef.hide();
this.getAllCities();
}
);
}

Mongoose Populate with express res.json() breaks

So I'm selecting Activities from the mongodb and populating User for each.
var query = Activity.find(query).populate("user");
return query.sort({created:"desc"}).exec(function(err, activities) {
debugger;
if (!err) {
return res.json(activities);
} else {
res.status(400).json(err);
}
});
As you can see I have a debugger; breakpoint is there, When I'm pring activities it prints an array of activities with the user object populated.
Also when I'm calling something like activities[0].toJSON() I get everything good!
But the response comes back with the user property empty !
I looked into the source of express.response.json(OBJ) and saw this line:
var body = JSON.stringify(val, replacer, spaces);
val is my activities
When calling JSON.stringify(activities) it will create a json with an empty user field.. any suggestions ?
Try the lean option. That gives back plain JS objects with no mongoose weirdness. Also, your error handling seems a little awkward, can be simplified.
var query = Activity.find(query).populate("user");
query.sort({created:"desc"}).lean().exec(function(err, activities) {
if (err) return res.status(400).json(err);
res.json(activities);
});
I would go even further, not hard-coding error sending in routes but simply passing along via if (err) return next(err) to error-handling middleware defined elsewhere in your app. You can still set the status, then use detection in your middleware, something like this:
app.use(function(err, req, res, next){
err.status = err.status || 500;
res.status(err.status).json(err);
});

Using node-mysql in a function

I'm very new to nodejs and have a question.
Trying to create a function that will call the value of any field where I mention its ID from a table:
function getUserInfo (userID, dynamicField) {
var query = connection.query('SELECT '+dynamicField+' from users WHERE userID = '+connection.escape(userID));
query.on('result', function(row) {
return(row.dynamicField);
});
};
console.log(getUserInfo(8, userEmail)) //this should get me the userEmail value of the user with userID=8
However, I get "undefined". If I use console.log rather than return, it logs the value but this has no use as a function to be used inside other functions to get a value.
I will be glad if I can get help for modifying the function.
This is a common mistake amongst async/nodejs beginners. You have essentially wrapped an async function inside a sync function which breaks down the nature of node's event loop. The return expression needs to be replaced with a callback. See below:
// Method
function getUserInfo (userID, dynamicField, callback) {
var query = connection.query('SELECT '+dynamicField+' from users WHERE userID = '+connection.escape(userID));
query.on('result', function(row) {
callback(null, row.dynamicField);
});
};
// Implementation
getUserInfo(8, userEmail, function(err, result){
console.log(err || result);
});
By convention, in Nodejs we always pass an error object first in the callback. In this case since there is no error to capture, we pass null in its place.