call a function with (req, res) inside other function in nodejs? - javascript

I have functions addVideosFromAuthor and schedule. I want schedule function will call addVideosFromAuthor and set the time to run. But when I call addVideosFromAuthor(), I got error TypeError: undefined is not iterable!. Look like the data can't be read in schedule function.
Is this code correct? Can you help me with this issue?
// #input array: [url, url2...]
export const addVideosFromAuthor = async (req, res) => {
try {
// processing...
} catch (error) {
console.log(error)
}
}
// #input object with array url: {command:'start', url: [url, url2...]}
export const schedule = (req, res) => {
const cmd = req.body.command
const task = cron.schedule('0 0 0 * * *', () => {
addVideosFromAuthor(req.body.url, res)
})
if (cmd === 'start') {
task.start()
} else if (cmd === 'stop') {
task.stop()
} else {
task.destroy()
}
}
Thank you

Related

Issue while trying to call an existing route from within another route in Express JS project

In an Express JS connected to a mySQL db, I am trying to get some data of an already defined route/ query:
// customers.model.js
CUSTOMERS.getAll = (result) => {
let query = "SELECT * FROM customers"
sql.query(query, (err, res) => {
if (err) {
console.log("error: ", err)
result(null, err)
return
}
result(null, res)
})
}
// customers.controller.js
// GET customers is a standalone route and should output all the customers when called.
const CUSTOMERS = require("../models/customers.model.js")
exports.findAll = (req, res) => {
return CUSTOMERS.getAll((err, data) => {
if (err)
res.status(500).send({
message: err.message ||
"Some error occurred while retrieving customers...",
})
else res.send(data)
})
}
In payments.controller.js I would firstly like to get all users so I can do something with the data:
// payments.controller.js
// GET payments is also a standalone route and should get the customers,
// do something with the data and output a calculation with the help of this data
const CUSTOMERS = require("../models/customers.model.js")
exports.calculateAll = (req, res) => {
const customers = CUSTOMERS.getAll((err, data) => {
console.log('this always has correct data', data)
if (err) return err
else return data
})
console.log('this is always undefined', customers)
...
res.send(whatEverCalculatedData)...
}
But that data here is always undefined.
What am I doing wrong in the above, and what's the correct way to call this route inside another route?
I know it has similarities with this question but I couldn't sort it out for my particular example.
It's due to your call which is asynchronous.
You must wait your data being ready before rendering the results.
Maybe you could to use Promises or async/await statements.
For example:
CUSTOMERS.getAll = async () => {
const query = "SELECT * FROM customers";
try {
return await sql.query(query);
} catch (e) {
console.log(`An error occurred while fetching customers: ${e.message}.`);
return null;
}
}
exports.calculateAll = async (req, res) => {
try {
const data = await CUSTOMERS.getAll();
res.send(whatEverCalculatedData);
} catch (e) {
res.send(`Something went wront: ${e.message}.`);
}
}

Can't get data via filter () in mongodb

I am trying to find the tasks assigned to the user through this
router.get('/all', auth, async (req, res) => {
try {
const assignments_raw = await Assignment.find({listP: listP.indexOf(req.user.userId)})
res.json(assignments_raw)
} catch (e) {
res.status(500).json({ message: 'Something went wrong, try again' })
}
})
Specifically, this line should have found all the tasks that have an element corresponding to the user ID inside the listP field
const assignments_raw = await Assignment.find({listP: listP.indexOf(req.user.userId)})
But this causes an error, why?
below is an excerpt from Mango
You can do like this
router.get('/all', auth, async (req, res) => {
try {
const assignments_raw = await Assignment.find()
let assignments = []
assignments_raw.map(assignment => {
if (assignment.listP.indexOf(req.user.userId) !== -1) {
assignments.push(assignment)
}
}
)
res.json(assignments)
} catch (e) {
res.status(500).json({ message: 'Something went wrong, try again' })
}
})

boolean from function is returning undefined node.js

I have 2 functions... 1st one in auth.js, which does this:
const adminCheck = (req, res) => {
console.log(“one”)
UtilRole.roleCheck(req, res, ‘ADMIN’, (response) => {
if(response) {
return true
} else {
return false
}
})
}
module.exports = {
adminCheck
}
basically checks if the user is an admin in my table. that works, but I am trying to retrieve the boolean in my function in my index.js function, which is below.
router.get(‘/viewRegistration’, auth.ensureAuthenticated, function(req, res, next) {
console.log("authcheck: " + auth.adminCheck())
const user = JSON.parse(req.session.passport.user)
var query = “SELECT * FROM tkwdottawa WHERE email = ‘” + user.emailAddress + “’”;
ibmdb.open(DBCredentials.getDBCredentials(), function (err, conn) {
if (err) return res.send(‘sorry, were unable to establish a connection to the database. Please try again later.’);
conn.query(query, function (err, rows) {
if (err) {
Response.writeHead(404);
}
res.render(‘viewRegistration’,{page_title:“viewRegistration”,data:rows, user});
return conn.close(function () {
console.log(‘closed /viewRegistration’);
});
});
});
})
where I am logging the value in the console.log right under where I initialize the function, it is returning undefined. how can I fix this?
You need to use Promise and wrap all callbacks to actually return a given result value from a function that uses a callback because usually a callback is called asynchronously and simply returning a value from it does not help to catch it in a calling function.
const adminCheck = (req, res) => {
console.log(“one”)
return new Promise(resolve, reject) => {
UtilRole.roleCheck(req, res, ‘ADMIN’, (response) => {
if(response) {
resolve(true)
} else {
resolve(false)
}
})
}
});
then you need to await a result calling this function using await keyword and marking a calling function as async:
router.get(‘/viewRegistration’, auth.ensureAuthenticated, async function(req, res, next) {
console.log("authcheck: " + await auth.adminCheck())
const user = JSON.parse(req.session.passport.user)
var query = “SELECT * FROM tkwdottawa WHERE email = ‘” + user.emailAddress + “’”;
ibmdb.open(DBCredentials.getDBCredentials(), function (err, conn) {
if (err) return res.send(‘sorry, were unable to establish a connection to the database. Please try again later.’);
conn.query(query, function (err, rows) {
if (err) {
Response.writeHead(404);
}
res.render(‘viewRegistration’,{page_title:“viewRegistration”,data:rows, user});
return conn.close(function () {
console.log(‘closed /viewRegistration’);
});
});
});
})
That's simple. You just forgot to return the inner function's return value
const adminCheck = (req, res) => {
console.log(“one”)
return UtilRole.roleCheck(req, res, ‘ADMIN’, (response) => {
if(response) {
return true
} else {
return false
}
})
}
module.exports = {
adminCheck
}

Not able to call a function in Javascript

I am calling the function createOne inside createProfile and createOne does not appear to be executed. I am trying to create a user in database. The route is working as expected its just i am not able to call function within a function.
Please help!
exports.createOne = Model =>
catchAsync(async (req, res, next) => {
console.log("I am in createone")
const doc = await Model.create(req.body);
res.status(201).json({
status: 'success',
data: {
data: doc
}
});
});
exports.createProfile = (req,res) => {
console.log(req.query.segment);
if(req.query.segment == "Tour"){
let Segment = Tour;
console.log(factory);
factory.createOne(Tour);
}
}
Kindly find below results of console log the function doesn't fire off at all.
Tour
{ getOne: [Function], createOne: [Function] }
POST /api/v1/midasCommon/?segment=Tour - - ms - -
The thing is, based on the definition of catchAsync you gave,
const catchAsync = fn => {
return (req, res, next) => {
fn(req, res, next).catch(next);
};
};
you are returning a function with catchAsync that never gets called. What you do with factory.createOne(Tour); is just call catchAsync, but you need one more call.
You can either do factory.createOne(Tour)(); or change createOne to be:
exports.createOne = Model =>
catchAsync(async (req, res, next) => {
console.log("I am in createone")
const doc = await Model.create(req.body);
res.status(201).json({
status: 'success',
data: {
data: doc
}
});
})(); // <-- Notice the call

High order function in express middleware

Can't send params to a high order function in JS. The function it's not getting req and res args
// In router.js
const { getAll } = require('./controller')
router.get('/coordinadores', getAll()('mentor'))
// In controller.js
exports.getAll = (req, res) => {
return (role) => {
var filter = { role }
if (req.user.role == 'mentor') filter = { role, centro: { "$in": req.user.centro } }
Model.find(filter, '-password -role -__v -createdAt -updatedAt -centro').lean().exec()
.then(list => { res.status(200).json({ list }) })
.catch(err => { errorHandler(req, res, err) })
}
}
// Result
// TypeError: Cannot read property 'user' of undefined
Here
router.get('/coordinadores', getAll()('mentor'))
you're calling getAll without any arguments. To create a HoF you should create it like this
const getAll = role => (req, res) => {
// your code
}
and then
router.get('/coordinadores', getAll('mentor'))
this will call the getAll function with mentor and it will return a function reference that will be called with req and res by express
For an alternate, express way is to pass values through middleware like:
function setDefaultRole((req, res, next) => {
if (not some check here) {
// if check fails, setting default role
req.user.role = 'mentor'
}
// call the next middleware
next();
})
function getAll((req, res, next) => {
if (req.user.role == 'mentor') {
// continue logic
filter = ???
}
})

Categories