How to reset global variable on every new HTTP POST request? - node.js

We are actually tring to read a csv file as input and throw out the corresponding results for the data in CSV file.
For every new http POST request, new result is being appended to the existing data in array(productDetails), but I want to flush the old data in array for every new request.
let productDetails=[];
router.get('/add-product',(req,res,next)=>{
res.sendFile(path.join(__dirname,'../','views','add-product.html'))
})
router.post('/add-product',(req,res,next)=>{
if (!req.files || Object.keys(req.files).length === 0) {
return res.status(400).send('No files were uploaded.');
}
else {
var sampleFile=req.files.file;
sampleFile.mv('././uploads/'+sampleFile.name,function(err){
if(err){
return res.status(500).send(err);
}
})
readFile('././uploads/'+sampleFile.name,'utf-8',(err,fileContent)=>{
if(err){
console.log(err); // Do something to handle the error or just throw it
throw new Error(err);
}
const jsonObj = csvjson.toObject(fileContent);
jsonObj.forEach(obj=>{
data.forEach(obj1=>{
if(obj.Make ==obj1.Make && obj.Manufacture == obj1.Manufacture && obj.Product==obj1.Product){
productDetails.push({
product:obj1.Product,
price:obj1.Price,
manufacture:obj1.Manufacture,
make:obj1.Make
})
}
})
})
})
}
res.redirect('/');
})
exports.routes=router;
exports.productDetails=productDetails;

You Can try by adding this line
router.post('/add-product',(req,res,next)=>{
productDetails=[];
//YOUR CODE
})

I think you need a function variable rather than a global variable for producrDetails, so if you define your variable inside the POST call it will work according to your requirements and start will an empty productDetails array on every POST call.
router.post('/add-product',(req,res,next)=>{
let productDetails=[]
// CODE
jsonObj.forEach(obj=>{
data.forEach(obj1=>{
if(obj.Make ==obj1.Make && obj.Manufacture == obj1.Manufacture && obj.Product==obj1.Product){
productDetails.push({
product:obj1.Product,
price:obj1.Price,
manufacture:obj1.Manufacture,
make:obj1.Make
})
}
})
})
}

Related

TypeError: validator.escape is not a function - (express-validator#6.12.1 package)

Codecademy video: link
Explanation:
As part of my Codecademy Back-End Engineer training, I have to do a project outside of their platform. The goal of this project is to make sure a node application is protected from common web attacks.
One challenge I faced was securing the code from Cross-Site Scripting (XSS) attacks. To do this, I used a package called express-validator#6.12.1. The code uses a function called validator.escape which is supposed to protect against any malicious code being inserted into an input form. However, I am getting an error in the console when I try to use it.
Terminal output :
TypeError: validator.escape is not a function
Here is the code :
const validator = require("express-validator");
app.post("/public_forum", function (request, response) {
if (request.session.loggedin) {
var comment = validator.escape(request.body.comment);
var username = request.session.username;
if (comment) {
db.all(
`INSERT INTO public_forum (username,message) VALUES ('${username}','${comment}')`,
(err, rows) => {
console.log(err);
}
);
db.all(`SELECT username,message FROM public_forum`, (err, rows) => {
console.log(rows);
console.log(err);
response.render("forum", { rows });
});
} else {
db.all(`SELECT username,message FROM public_forum`, (err, rows) => {
console.log(rows);
console.log(err);
response.render("forum", { rows });
});
}
comment = "";
} else {
response.redirect("/");
}
comment = "";
//response.end();
});
In the video of Codecademy, the guy uses this function.
Try with:
const {check, validationResult} = require('express-validator');
app.post('/public_forum', async function (request, response) {
if (request.session.loggedin) {
await check('comment').trim().escape().run(req);
const validationResult = await validationResult(req);
if (validationResult.isEmpty()) {
// Good to go...
const { comment } = req.body;
}
...
Link to official docs
I have implemented your code. I tried to add both a malicious and safe comment, but I got an error message on my browser that said, "Port 4000 Not Found." Every time I run the code, it kills the port. So I have implemented another code that works well based on what you sent me.
// This code defines a post request handler for the "/public_forum" endpoint.
app.post('/public_forum', async function (request, response) {
// Check if the user is logged in by checking the session data.
if (request.session.loggedin) {
// Trim and escape the incoming comment.
await check('comment').trim().escape().run(request);
// Get the validation result of the incoming comment.
const errors = validationResult(request);
// If the validation result contains errors, return a 400 status with the errors in a JSON format.
if (!errors.isEmpty()) {
return response.status(400).json({ errors: errors.array() });
}
// Get the comment from the request body.
const { comment } = request.body;
// If a valid comment exists, insert it into the "public_forum" database table.
if (comment) {
db.run(
`INSERT INTO public_forum (username,message) VALUES (?,?)`, [request.session.username, comment],
(err) => {
// If an error occurs while inserting the comment, log the error.
if (err) {
console.error(err);
}
}
);
}
// Select all the rows from the "public_forum" table.
db.all(`SELECT username,message FROM public_forum`, (err, rows) => {
// If an error occurs while selecting the rows, log the error.
if (err) {
console.error(err);
}
// Log the selected rows.
console.log(rows);
// Render the "forum" template, passing in the selected rows as a parameter.
response.render("forum", { rows });
});
} else {
// If the user is not logged in, redirect them to the homepage.
response.redirect("/");
}
});

Handling Multiple functionalities in Firebase using Nodejs

Hellow all,
I'm Newbie to Nodejs and Firebase, I need two functionalities to takes place in a single function and also I have written a piece of code it's works fine.
But My question is, the code I have written is the correct way to achieve the multiple functionality or do we have any other alternate method(correct way) to achieve the same functionality.
Doubt :
Retrieving relevant details of project ----> Inside Callback function ----> saving data to another table ----> Inside Callback function ----> Deleting data from table -----> Inside Callback function ----> response
Do we need to write the functionality inside the nested callback function to achieve the output or is there is any other way to achieve it .
// Nodejs Post Function
app.post('/delete_user_request_project/', function (req, res)
{
if (!is_admin_login(req.cookies.login_type))
{
return res.redirect('/');
}
var project_id = req.body.project_id; // Getting the project Id
let del_ref = admin.database().ref("user_request_project/" + project_id); // Targeting the details of the project to fetch that particular data
del_ref.once("value", function (snapshot)
{
var request_project_obj = snapshot.val(); // fetching the details of project
if (request_project_obj != null)
{
let update_ref = admin.database().ref("deleted_user_request_project/" + project_id);
update_ref.set(
request_project_obj // Updating project details to another table
).then(function ()
{
del_ref.remove().then(function () // Deleting the details from project Table
{
return res.status(200).send('success');
});
});
}
else
{
var error = "プロジェクトが存在しない";
req.flash("error", error_message);
return res.send({
status: 'error',
error: error
});
}
});
})
TIA
I would suggest you use the Promise version of the once() method instead of the Callback version, as follows. It will allow you to correctly chain the different promises returned by the asynchronous Firebase method.
app.post('/delete_user_request_project/', function (req, res) {
if (!is_admin_login(req.cookies.login_type)) {
return res.redirect('/');
}
var project_id = req.body.project_id; // Getting the project Id
let del_ref = admin.database().ref("user_request_project/" + project_id); // Targeting the details of the project to fetch that particular data
del_ref.once("value")
.then(function (snapshot) {
var request_project_obj = snapshot.val(); // fetching the details of project
if (request_project_obj != null) {
let update_ref = admin.database().ref("deleted_user_request_project/" + project_id);
return update_ref.set(request_project_obj); // Updating project details to another table
}
else {
throw new Error('request_project_obj null');
}
})
.then(function () {
return del_ref.remove();
})
.then(function () // Deleting the details from project Table
{
return res.status(200).send('success');
})
.catch(function (error) {
if (error.message === 'request_project_obj null') {
var error = "プロジェクトが存在しない";
req.flash("error", error_message);
return res.send({
status: 'error',
error: error
});
} else {
//...
}
})
})

Angular showing "Cannot read property 'friends' of null"

Hi I am trying trying to get data from my nodejs backend to angular. And i get the below error message in nodejs
Cannot read property 'friends' of null
at UserModel.findOne.select.lean.exec
The Api Works fine, if i try to use in postman. But when used in angular i get the error message in nodejs
The server side code is:
let findFriends = ()=>{
return new Promise((resolve, reject)=>{
UserModel.findOne({userId: req.body.userId || req.query.userId})
.select('-__v -_id -password')
.lean()
.exec((err, userFriends)=>{
console.log(userFriends.friends.length)
if(err){
logger.error(err.message, ' friendsController: getAllNonFriends, findFriends', 5)
let apiResponse = response.generate(true, `Failed to Find Friends`, 500, null)
reject(apiResponse)
}else {
if(userFriends.friends.length !== 0){
resolve(userFriends.friends)
}else {
resolve(userFriends)
}
}
})
})
} // end find requests
the code in angular:
public allNonFriends: any = ()=>{
this.http.getNonFriendsList(this.currentUser).subscribe(
(apiResponse)=>{
console.log(apiResponse)
if(apiResponse.status === 200){
console.log(apiResponse.data)
} else {
console.log(apiResponse.message)
}
},
(err)=>{
console.log(err)
}
)
} // end all non friends
I found the solution. I change the parameter from body to query and it worked

NodeJs/React- How to store query results from firestore in variable

function collectres () {
var store ='';
var docRef = db.collection("cities").doc("SF");
docRef.get()
.then(function (doc) {
if (doc.exists) {
console.log("Document data:", doc.data());
store = doc.data();// when referenced outside, it doesnt hold anything.
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
})
.catch(function (error) {
console.log("Error getting document:", error);
});
return store; // returns nothing and seems to not notice the assignment.
}
I have this problem, where i want to store firebase query results into a variable. However, when i try and assign the variable some data from the query, it seems to not be able to store it.
Any help or advice in the right direction would help.
Edit 1:
After implementing the callback function, i was wondering how to set the state for a component or permanently store the results so that many components can access it.
user.CollectRes(function(store){
console.log(store.name);
name =store.name;
console.log(name);
// this.setState({name:store.name});
});
console.log(name); // want to be able to reference this outside the callback function. So i can display it on the page.
It is because JavaScript is asynchrone.
Because of that, your variable doc doesn't exists yet outside your .then function.
To return this value, you can use Promises way, or easier, you can have a callback function to return your document like this :
function collectres (callback) {
var docRef = db.collection("cities").doc("SF");
docRef.get().then(function (doc) {
if (doc && doc.exists) {
callback(doc.data()); // Return your data inside the callback function
} else {
callback(null); // Return null if data doesn't exists
}
}).catch(function (error) {
callback(null); // Return null in error case
});
}
collectres(function (store) { // Call collectres to get your data
console.log(store);
// continue here
});
I recommand you to read this article to learn more about asynchronous.
Hope it helps.

Trying to implement callback, or some way to wait until my get request is done. This is in node.js express

Im trying to implement some way to stop my code to redirect me before I get the response from the omdb api I am using.
My function for making a search for a movie and saving all titles in a session looks like this:
app.post('/search', isLoggedIn, function(req, res) {
function getMovies(arg, callback){
console.log('In getMovies');
console.log('searching for '+arg);
omdb.search(arg, function(err, movies) {
if(err) {
return console.error(err);
}
if(movies.length < 1) {
return console.log('No movies were found!');
}
var titles = [];
movies.forEach(function(movie) {
// If title exists in array, dont push.
if(titles.indexOf(movie.title) > -1){
console.log('skipped duplicate title of '+movie.title);
}
else{
titles.push(movie.title);
console.log('pushed '+movie.title);
}
});
// Saves the titles in a session
req.session.titles = titles;
console.log(req.session.titles);
});
// Done with the API request
callback();
}
var title = req.body.title;
getMovies(title, function() {
console.log('Done with API request, redirecting to GET SEARCH');
res.redirect('/search');
});
});
However I dont know if I implement callback in the right way, because I think there can be a problem with the api request actually executing before the callback, but not finishing before. And therefor the callback is working..
So I just want 2 things from this question. Does my callback work? And what can I do if a callback won't solve this problem?
Thankful for all answers in the right direction.
Add
callback();
To, like this
omdb.search(arg, function(err, movies) {
if (err) {
return console.error(err);
}
if (movies.length < 1) {
return console.log('No movies were found!');
}
var titles = [];
movies.forEach(function(movie) {
// If title exists in array, dont push.
if (titles.indexOf(movie.title) > -1) {
console.log('skipped duplicate title of ' + movie.title);
} else {
titles.push(movie.title);
console.log('pushed ' + movie.title);
}
});
// Saves the titles in a session
req.session.titles = titles;
callback();
});
omdb.search is asynchronous function that's why callback executed before omdb.search

Resources