Add to cart not working Nodejs Expressjs Mysql - mysql

this is the code of products.js in controller
let cart = [];
function addToProduct(products) {
cart.push(products);
}
exports.addToCart = (req, res) => {
const productId = req.params.id;
const sql = `SELECT * FROM products WHERE id = ${productId}`;
connection.query(sql, (error, result) => {
if (error) {
return res.send('Error adding to cart');
} else {
res.redirect('/allProducts');
addToProduct(result);
console.log("length of cart is"+cart.length);
for(let i= 0; i < cart.length; i++) {
console.log(cart[i]);
}
}
});
};
function getProducts() {
return cart.map(product => ({
name: product.name,
description: product.description,
price: product.price,
stock: product.stock
}));
}
function getTotal() {
return cart.reduce((total, product) => total + product.price * product.stock, 0);
}
exports.getCart = (req, res, next) => {
const products = getProducts();
const total = getTotal();
req.cart = { products, total };
return next();
};
and this is the code of pages.js in routes
router.post('/add-to-cart/:id', productsController.addToCart);
router.get('/cart', productsController.getCart, (req, res) => {
res.render('cart', {
products: req.cart.products,
total: req.cart.total
});
});
now i am not getting the products in my cart.hbs it is just empty and not showing errors. Exports.addtocart is working fine but the problem is after that. please help me recognize it.
i tried many things but still end up here

Related

NodeJS with MySQL - Return blank Array

I have initialized an array "userTasklist". I have pushed the object in this array in .map function. After .map, I have console this Array but array is blank.
Than I have console the object in .map function and all the value print successfully but in Array there are no value. Don't know why.
exports.allUserList = (req, res) => {
let userID = req.params.userid;
const ghusersQuery = "SELECT user_id, name, employee_code FROM users WHERE under_gh = ?";
conn.query(ghusersQuery, [userID], (err, userdata) => {
if (err) {
res.send({ message: err })
} else {
if (userdata && userdata.length > 0) {
let userTasklist = [];
userdata.map((datauser) => {
var objtask = {};
const userDataQuery = "SELECT * FROM tasklist WHERE user_id = ?";
conn.query(userDataQuery, [datauser.user_id], (errnew, taskdata) => {
if (taskdata && taskdata.length > 0) {
objtask = {
userid: datauser.user_id,
tasklist: taskdata
}
userTasklist.push(objtask);
}
})
})
console.log(userTasklist)
res.send({ message: "user list fetched", userdata: userdata, tasklistdata: userTasklist })
} else {
res.send({ message: "Data not found!" })
}
}
})
}
Simplified solution using mysql21 for handling queries as Promises.
exports.allUserList = async (req, res) => {
const { userid } = req.params
const users = await connection.query('SELECT user_id, name, employee_code FROM users WHERE under_gh = ?', [userid])
if (!users.length)
return res.send({ message: "Data not found!" })
// better fetch all relevant tasks in bulk
const tasks = await connection.query('SELECT * FROM tasklist WHERE user_id IN (?)', [users.map(r => r.user_id)])
res.send({ message: "user list fetched", users, tasks })
}

When I try to take the id it takes it as an undefined variable

When I try to take the id it takes it as an undefined variable, but if I just do the res.send () there is no problem Well, I can't think of what to do, have I made several attempts during days, any recommendations?
router.get('/products/:id', (req, res) => {
const id = req.params.id;
const idsiguiente = req.params.id + 1;
const idanterior = req.params.id - 1;
var numero_de_articulos = 16;
const iniciar = (id - 1) * numero_de_articulos;
console.log(req.params.id);
conexion.query('SELECT COUNT(*) AS cuenta_productos FROM Products', (error, cuenta_productos) => {
if (error) throw error;
var paginas = cuenta_productos[0]['cuenta_productos'] / numero_de_articulos;
paginas = Math.ceil(paginas);
conexion.query('SELECT * FROM Products limit ?,?', [iniciar, numero_de_articulos], (error, productos) => {
if (error) throw error;
//res.send(productos);
res.render('products', {
products: productos,
id: id,
paginas: 1,
siguiente: idsiguiente,
anterior: idanterior
});
})
})
});

how can i stop mysql from updating a table automatically

am running a cronjob to update a user table every midnight, when I stop the Nodejs application, the table keep updating by itself, and have already stop the application.
here is the nodejs code I use for the job
const CronJob = require('cron').CronJob;
const logger = require("../helpers/logger");
const { updateUser } = require("../helpers/user");
const db = require("../models/db");
const job = new CronJob('* * * * *', async function() {
db.query("UPDATE sponsored_posts SET post_status = 0", (err, data) => {
if (err) logger.debug(err)
});
db.query("DELETE FROM sponsored_posts", (err, data) => {
if (err) logger.debug(err)
});
//EXPIRING USER
db.query("SELECT * FROM all_users WHERE membership_expired > 0", async (err, data) => {
if (data.length > 0) {
//FIlter Through All User
//Deduct While They Havent Expired
await data.map(async user => {
await updateUser({
uid: parseInt(user.uid),
membership_expired: user.membership_expired - 1
})
})
}
})
db.query("SELECT * FROM all_users WHERE membership_expired = 0", async (err, data) => {
if (data.length > 0) {
//FIlter Through All User
//Set Can Purchase To 1
await data.map(async user => {
await updateUser({
uid: parseInt(user.uid),
can_purchase: 1
})
})
}
});
}, null, false, "Africa/Lagos");
job.start();

How to insert records in the database and then update some fields?

I want to do a multiplication of items that are separated into groups in my database a certain number of times but when doing the multiplication I need to change the value of a field called GroupNumber.
For this, I am making two HTTP requests within a looping (FOR).
The first one does the copy of what I need and the second one does an UPDATE in the GroupNumber field.
image 1
As you can see the copy is done 3 times, but the value of GroupNumber (Group #) assumes the value of the group of products copied +1 (in case '2') and remains so. I would like the copy to be shown below.
Image 2
Follow the code for review:
products.component.ts
copyProductsOfGroup() {
const quoteID = + this.activatedRoute.snapshot.paramMap.get('id');
const groupNumber = this.copyGroupProductsForm.get('copyGroup').value
const multiplier = this.copyGroupProductsForm.get('multiplier').value
for (let i = 0; i < multiplier; i++) {
this.productService.copyGroupProduct(quoteID, groupNumber)
.subscribe(
(cloneProductsInfos) => {
this.cloneProductsInfos = cloneProductsInfos
console.log(this.cloneProductsInfos)
},
(err) => {
console.log(err)
},
() => {
this.productService.updateCopyGroupProduct(this.groupNumber, this.cloneProductsInfos.insertId, this.cloneProductsInfos.affectedRows)
.subscribe(
(data) => {
console.log(data)
},
(err) => {
console.log(err)
},
() => {
this.getQuotesProducts()
this.filterGroupNumber()
this.modalService.dismissAll()
}
)
}
)
}
}
Service:
product.service.ts
copyGroupProduct(quoteID: number, groupNumber: number): Observable<CloneProductsModel> {
const url = `http://localhost:9095/copy-group/${quoteID}/${groupNumber}`
return this.http.get<CloneProductsModel>(url)
}
updateCopyGroupProduct(newGroupNumber: number, insertID: number, affectedRows: number): Observable<CloneProductsModel> {
const url = `http://localhost:9095/copy-group-update/${newGroupNumber}/${insertID}/${affectedRows}`
return this.http.get<CloneProductsModel>(url)
}
Nodejs and MySQL:
// Copy productGroup
app.get('/copy-group/:quoteID/:groupNumber', function (req, res) {
let quote_id = req.params.quoteID;
let groupNumber = req.params.groupNumber;
mydb.query(`
INSERT INTO products (
ProductName,
ProductElement,
ProductAttribute,
ProductAttributeValue,
Quantity,
ProductNotes,
FK_ID_QUOTE,
ID_POF,
ID_POE
)
(
SELECT
ProductName,
ProductElement,
ProductAttribute,
ProductAttributeValue,
Quantity,
ProductNotes,
FK_ID_QUOTE,
ID_POF,
ID_POE
FROM products AS P
WHERE P.FK_ID_QUOTE = ${quote_id} AND P.GroupNumber = ${groupNumber}
)`,
function (error, results, fields) {
if (error) throw error;
console.log(results)
return res.send(results);
});
});
app.get('/copy-group-update/:newGroupNumber/:insertID/:affectedRows', function (req, res) {
let newGroupNumber = req.params.newGroupNumber;
let insertID = req.params.insertID;
let affectedRows = req.params.affectedRows;
console.log(newGroupNumber)
console.log(insertID)
console.log(affectedRows)
mydb.query(`
UPDATE products AS P
SET P.GroupNumber = ${newGroupNumber}
WHERE P.ID BETWEEN ${insertID} AND (${insertID} + ${affectedRows} - 1)
`,
function (error, results, fields) {
if (error) throw error;
console.log(results)
return res.send(results);
})
})

mysql node: can't set headers after they are sent

I am trying to get a list of movies in a directory, parse titles, get movie information on TMDB than check if movie info is stored in mysql database and if not stored, insert info into the database.
I am using NodeJS/Express and mysql.
Here is my code so far:
exports.checkForMovies = function (req, res, next) {
const testFolder = './test/';
var movieList = [];
var movieResultsPromise = [];
var movieResults = [];
fs.readdirSync(testFolder).forEach(file => {
movieList.push(tnp(file));
});
movieList.forEach(movie => {
var waitPromise = searchTMDB(movie.title);
movieResultsPromise.push(waitPromise);
});
Promise.all(movieResultsPromise).then(result => {
movieResults = result;
movieResults.forEach(movie => {
checkMoviesInDB(movie.id, (err, data) => {
if (err) {
console.log(err)
}
if (data && data.update === true) {
var movieObj = {
m_tmdb_id: movie.id
};
insertMoviesToDB(movieObj, (resp, err) => {
if (err) {
console.log(err);
} else {
return res.json(resp);
}
});
} else {
return res.json(data);
}
});
});
});
}
function checkMoviesInDB(id, cb) {
var sql = "SELECT * FROM ?? WHERE m_tmdb_id = ?"
var table = ['movie', id];
sql = mysql.format(sql, table);
connection.query(sql, function (err, rows) {
if (err) {
return cb(err);
}
if (rows.length > 0) {
return cb(null, {
success: true,
update: false,
message: 'Movies up to date!'
})
} else {
return cb(null, {
update: true,
message: 'Updating database!'
})
}
});
}
function insertMoviesToDB(movie, cb) {
var sql = "INSERT INTO ?? SET ?";
var table = ['movie', movie];
sql = mysql.format(sql, table);
connection.query(sql, function (err, rows) {
if (err) {
return cb(err);
} else {
return cb(null, {
success: true,
message: 'Movie database updated!'
})
}
});
}
function searchTMDB(title) {
return new Promise((resolve, reject) => {
https.get(config.tmdbURL + title, response => {
var body = "";
response.setEncoding("utf8");
response.on("data", data => {
body += data;
});
response.on("end", () => {
body = JSON.parse(body);
resolve(body.results[0]);
});
response.on("error", (err) => {
reject(err);
});
});
});
}
After code execution it inserts movie info in the database or responses with "Movies up to date" but I am getting this error and NodeJS crashes:
Error: Can't set headers after they are sent.
Any help is appreciated, thanks!
EDIT!
This is the new code and I am still getting the same error...
exports.checkForMovies = function (req, res) {
const testFolder = './test/';
var movieList = [];
var movieResults = [];
fs.readdirSync(testFolder).forEach(file => {
movieList.push(tnp(file));
});
var movieObj = movieList.map(movie => {
var tmp = [];
return searchTMDB(movie.title).then(data => {
tmp.push(data);
return tmp
});
});
var checkDB = Promise.all(movieObj).then(moviesData => {
moviesData.map(movieData => {
checkMoviesInDB(movieData[0]).then(checkResponse => {
if (!checkResponse.movieToInsert) {
res.json(checkResponse);
} else {
var insertArray = checkResponse.movieToInsert;
var inserting = insertArray.map(movie => {
var movieObject = {
m_tmdb_id: movie.id,
m_name: movie.title,
m_year: movie.release_date,
m_desc: movie.overview,
m_genre: undefined,
m_poster: movie.poster_path,
m_watched: 0
};
insertMoviesToDB(movieObject).then(insertResponse => {
res.json(insertResponse);
});
});
}
});
});
});
}
function checkMoviesInDB(movie) {
var moviesToInsert = [];
return new Promise((resolve, reject) => {
var sql = "SELECT * FROM ?? WHERE m_tmdb_id = ?"
var table = ['movie', movie.id];
sql = mysql.format(sql, table);
connection.query(sql, function (err, rows) {
if (err) {
return reject(err);
}
if (rows.length === 0) {
moviesToInsert.push(movie);
resolve({
success: true,
movieToInsert: moviesToInsert
});
} else {
resolve({
success: true,
message: 'No movie to insert'
});
}
});
});
}
function insertMoviesToDB(movie) {
return new Promise((resolve, reject) => {
var sql = "INSERT INTO ?? SET ?";
var table = ['movie', movie];
sql = mysql.format(sql, table);
connection.query(sql, function (err, rows) {
if (err) {
return reject(err);
} else {
resolve({
success: true,
message: 'Movie added!'
});
}
});
});
}
function searchTMDB(title) {
return new Promise((resolve, reject) => {
https.get(config.tmdbURL + title, response => {
var body = "";
response.setEncoding("utf8");
response.on("data", data => {
body += data;
});
response.on("end", () => {
body = JSON.parse(body);
resolve(body.results[0]);
});
response.on("error", (err) => {
reject(err);
});
});
});
}
Auth.js
const config = require('./config');
const jwt = require('jsonwebtoken');
module.exports = function (req, res, next) {
var token = req.body.token || req.params.token || req.headers['x-access-token'];
if (token) {
jwt.verify(token, config.secret, function (err, decoded) {
if (err) {
return res.json({
success: false,
message: 'Failed to authenticate token.'
});
} else {
req.decoded = decoded;
next();
}
});
} else {
return res.status(403).send({
success: false,
message: 'Please login in to countinue!'
});
}
};
Hope this helps:
// Bad Way
const checkForMovies = (req, res) => {
const movieList = ['Braveheart', 'Highlander', 'Logan'];
movieList.forEach(movie => {
res.json(movie); // Will get Error on second loop: Can't set headers after they are sent.
})
}
// Good Way
const checkForMovies = (req, res) => {
const movieList = ['Braveheart', 'Highlander', 'Logan'];
const payload = { data: { movieList: [] } };
movieList.forEach(movie => {
payload.data.movieList.push(movie);
});
// send res once after the loop with aggregated data
res.json(payload);
}
/* GET home page. */
router.get('/', checkForMovies);