Unable to return value from function - node.js

I'm getting undefined on return value from the function
function checkAveStorage(path) {
console.log("path " + path);
disk.check(path, function(err, info) {
if (err) {
console.log(err);
return -1;
} else {
console.log("info " + info.available);
return ((info.available / info.total) * 100).toFixed(2);
}
});
}
app.get("/sysinfo", (req, res, next) => {
var storage = checkAveStorage('/mnt/usb');
console.log(storage);
})
undefined value appear in console.

You are using callback which cannot return value, but you can use it inside that call back only. Other options are use promise or async/await.
function checkAveStorage (path) {
console.log('path ' + path)
return new Promise((resolve, reject) => {
disk.check(path, function (err, info) {
if (err) {
console.log(err)
reject(-1)
} else {
console.log('info ' + info.available)
resolve(((info.available / info.total) * 100).toFixed(2))
}
})
})
}
app.get('/sysinfo', (req, res, next) => {
checkAveStorage('/mnt/usb').then((storage => {
console.log(storage)
}), (err) => {
console.log(err)
})
})
Another way with async/await
async function checkAveStorage(path) {
try{
const info = await disk.check(path);
return ((info.available / info.total) * 100).toFixed(2);
} catch(err){
console.log(err);
return -1;
}
}
app.get("/sysinfo", async (req, res, next) => {
var storage = await checkAveStorage('/mnt/usb');
console.log(storage);
})

You are using callback so you must :
app.get("/sysinfo", (req, res, next) => {
checkAveStorage('/mnt/usb').then((storage)=>{
console.log(storage)
})

Related

How to get data from multiple model in single controller in NodeJS?

I am working on nodejs and i am using "Express js" framework, I am working on Controller and i am trying to get data from "two model functions" but i am getting message "anonymous", How can i get data from multiple "model functions", Here is my code,
This is my homeController
homeController.index = function (req, res, next) {
// fetching data into 'data variable' from FetchRecords model
homeModel.FetchRecords(function (err, data) {
if (err) {
req.flash('error', 'There was no records.');
} else {
res.render('home/index', { data: data });
}
});
homeModel.getAverage(function (average) {
console.log(average);
// res.render('home/index',{data:average});
});
};
This is my homeMOdel
homeModel.FetchRecords = function (data) {
sql.query('SELECT * FROM rating', function (err, res) {
if (err) {
return data(err, null);
} else {
return data(null, res);
}
});
};
homeModel.getAverage = function (average) {
console.log(average);
sql.query('SELECT avg(value) FROM rating', function (err, res) {
if (err) {
return average(err, null);
} else {
return average(null, res);
}
});
};
Inside homeModel just create 1 function instead of 2 separate. You can combine both MySQL queries into one like this.
const FetchRecordsAndAverage = function (data) {
sql.query('SELECT * FROM rating; SELECT avg(value) FROM rating', function (err, res) {
if (err) {
return data(err, null);
} else {
return data(null, res);
}
});
};
module.exports = {
FetchRecordsAndAverage
}
With this you will get combined data of both queries as arrays inside array.
Result of queries can be accessed as data[0] & data[1].
You should export the function from the home model:
const FetchRecords = function (data) {
sql.query('SELECT * FROM rating', function (err, res) {
if (err) {
return data(err, null);
} else {
return data(null, res);
}
});
};
const getAverage = function (average) {
console.log(average);
sql.query('SELECT avg(value) FROM rating', function (err, res) {
if (err) {
return average(err, null);
} else {
return average(null, res);
}
});
};
module.exports = {
FetchRecords,
getAverage
}
And retrieve them in your application by calling:
const { FetchRecords, getAverage } = require('./path/to/home_model');

how do I return documents back to my API call?

I am trying to call method get_radar_life_cycle from app.get("/api/radar_cloning and it throws the error shown below,
error is coming from line return done(null,documents) how do I return documents back to my API call?
METHODS:-
let get_cloned_radars = function(documents, done) {
let complete_radar_list=[]
for (let i = 0; i < documents.length; i++) {
complete_radar_list.push(documents[i]['orgRadar']);
for (let j = 0; j < documents[i]['clonedRadarsdetailslist'].length; j++) {
complete_radar_list.push(documents[i]['clonedRadarsdetailslist'][j]['clonedRadar']);
}
}
data = complete_radar_list
return done(null, data)
}
let get_radar_life_cycle = function(data,done) {
console.log("data after get_radar_life_cycle")
console.log(data)
Radar_life_cycle.find({orgRadar: {$in:data}})
.then(documents => {
console.log(documents) --> shows correct data
});
return done(null,documents) --> Error is coming from this line
};
API call:
app.get("/api/radar_cloning", (req, res, next) => {
Radar_cloning.find({orgRadar: {$in:req.query.params.split(',')}})
.then(documents => {
get_cloned_radars(documents, function(err,data) {
if (err) {
res.json(err);
if (data!=null){
console.log(data)
}//end for data
}//end of (Err)
});//get_cloned_radars
get_radar_life_cycle(data, function(err,radar_life_cycle_data) {
if (err) {
res.json(err);
console.log(radar_life_cycle_data)
}//end for radar_life_cycle_data
}//end of (Err)
});//end of get_radar_life_cycle
});
});
ERROR:-
(node:10065) UnhandledPromiseRejectionWarning: ReferenceError: documents is not defined
You are trying to access documents outside of its scope, the scope being everything between the { and }. So you cannot access it below the .then(() => {}) scope.
Luckily you are are providing a callback function called done(err, radar_life_cycle_data), which you can use anywhere in the scope of the get_radar_life_cycle(documents, done) function. Even the scopes inside of its scope. When you are calling the done function, what you are basically doing is calling this function (well it has some syntax errors, so I cleaned it up)
function(err,radar_life_cycle_data) {
if (err) {
res.json(err);
console.log(radar_life_cycle_data)
}
}//end for radar_life_cycle_data
which then gets executed
So the solution:
Move your done in your .then(() => {}) scope like this:
let get_radar_life_cycle = function(data,done) {
console.log("data after get_radar_life_cycle")
console.log(data)
Radar_life_cycle.find({orgRadar: {$in:data}})
.then(documents => {
console.log(documents) // --> shows correct data
done(null,documents) // --> No error coming from this line
});
};
Same goes for the data it is not in the scope of the get_cloned_radars
app.get("/api/radar_cloning", (req, res, next) => {
Radar_cloning.find({orgRadar: {$in:req.query.params.split(',')}})
.then(documents => {
get_cloned_radars(documents, function(err,data) {
if (err) {
res.json(err);
if (data!=null) {
console.log(data)
get_radar_life_cycle(data, function(err,radar_life_cycle_data) {
if (err) {
res.json(err);
console.log(radar_life_cycle_data)
} //end of (Err)
}); //end of get_radar_life_cycle
} //end for data
} //end of (Err)
}); //get_cloned_radars
});
But since your code is unreadable, here is a cleaned up version:
app.get("/api/radar_cloning", (req, res, next) => {
const radar_life_cycle_cb = function (err, data) {
if (err) {
res.json(err);
return;
}
console.log(data);
}
const cloned_radar_cb = function (err, data) {
if (err) {
res.json(err);
return;
}
if (data != null) {
get_radar_life_cycle(data, radar_life_cycle_cb);
}
};
Radar_cloning.find({orgRadar: {$in:req.query.params.split(',')}})
.then(documents => get_cloned_radars(documents, cloned_radar_cb));
}

How to put router in function and export it?

I try to put router.post in a function and export it to app.js. But it didn't take effect. Here is my code.
crypto.js
function getPublicKey() {
console.log('111');
router.post('/get-public-key', (req, res) => {
fs.readFile(__dirname + '/keys/rsa-pub.pem', 'utf8', (err, data) => {
if (err) {
throw err
} else {
res.send(data)
}
})
});
}
module.exports = {
getPublicKey
}
app.js
const cryptoRouter = require('./modules/crypto/router');
cryptoRouter.getPublicKey();
It printed '111'.But I cannot POST /get-public-key.
How should I do?Thanks!
I think getPublicKey should return the public key instead
function getPublicKey() {
fs.readFile(__dirname + '/keys/rsa-pub.pem', 'utf8', (err, data) => {
if (err) {
throw err
}
return data
})
}
Then, in app.js
app.post('/get-public-key', (req, res) => {
res.send(getPublicKey)
})
Edit
If you wanna use router, you should do like this:
// ./routes/somewhere.js
const router = require('express').Router()
router.post('/something', (req, res) => {
res.send('You made it!')
})
module.exports = router
Then
// ./app.js
app.use('/somewhere', require('./routes/somewhere'))
Finally, you can make a post request to /somewhere/something.
You can pass the instance of app to your function and return the route
function getPublicKey(app) {
console.log('111');
return app.post('/get-public-key', (req, res) => {
fs.readFile(__dirname + '/keys/rsa-pub.pem', 'utf8', (err, data) => {
if (err) {
throw err
} else {
res.send(data)
}
})
})
}
module.exports = {
getPublicKey
}
Then in your app.js you could simply invoke by passing in the instance of app:
const cryptoRouter = require('./modules/crypto/router');
cryptoRouter.getPublicKey(app);

Async function call in if/else not returning value

I'm stuck trying to pull an async value within an if/else, I've resolved a number of errors but the following is returning empty brackets:
router.post('/api/shill', async (req, res) => {
let checkIdLength = req.body.Id;
let checkIP = validateIP(req.body.Ip);
let checkPort = Number.isInteger(req.body.Port);
console.log(req.body.Id);
if (checkIdLength.length != 66 || checkIP != true || checkPort != true || typeof req.body.Wumbo != "boolean") {
res.status(400).send('Invalid value(s) detected');
}
else try {
challengeInvoice = getInvoice();
res.status(200).send(challengeInvoice);
} catch (e) {console.log(e)}
})
async function getInvoice() {
await lnd.addInvoice({}, (err, res) => {return res});
}
fwiw, the lnd.addInvoice is tied to a grpc call
You can use promises for async data.
try {
getInvoice().then(challengeInvoice => {
res.status(200).send(challengeInvoice);
})
} catch (e) {console.log(e)}
then
function getInvoice() {
return new Promise( (resolve, reject) => {
lnd.addInvoice({}, (err, result) => {
if(err) {
reject(err);
}
else{
resolve(result)
}
});
});
}

Promise not returned warning in Bluebird

I am getting an error that seems to suggest I'm not returning some of my statements, but I think I'm doing everything correctly. Here's the warning:
Warning: a promise was created in a handler at /src/api/podcasts.js:51:18 but was not returned from it
This is the code of the function in question:
'findPodcastById': (db, podcastId, callback) => {
var queryString = "SELECT * FROM podcasts WHERE id=$1;";
db.one(queryString, [podcastId])
.then((result) => {
return callback(null, result);
})
.catch((err) => {
return callback(err, null);
});
},
And the parent function that it's called from:
app.post('/getepisodes', (req, res, next) => {
var podcastId = req.body.podcastId;
var userId = req.body.userId;
var podcast;
podcasts.findPodcastByIdAsync(db, podcastId)
.then((result) => {
podcast = result;
return request(podcast.rss);
})
.then((result) => {
return podcastParser.parseAsync(result, {})
})
.then((result) => {
return Promise.resolve(result.channel.items);
})
.map((item) => {
var date = new Date(item.pubDate).toLocaleString();
return podcasts.addEpisodeAsync(db, podcast.id, item.title, item.enclosure.url.split('?')[0], striptags(item.description), date, item.duration);
})
.map((episode) => {
return posts.addPostAsync(db, 'podcast', episode.id, episode.title, episode.description);
})
.then(() => {
return podcasts.findEpisodesByPodcastIdAsync(db, podcastId, userId);
})
.then((result) => {
return res.json(result);
})
.catch((err) => {
next(err);
});
});
I have a return statement in each promise block, so I'm not sure what I'm doing wrong, I would really appreciate some help!
findPostCastBy id is not returning the promise, try this
'findPodcastById': (db, podcastId) => {
return db.one("SELECT * FROM podcasts WHERE id=$1;", [podcastId])
}

Resources