Unable to return/get response from closure - node.js

I want to get the result from the closure function. I did try doing some callback functions too but still I'm getting the same issue. I was able to console.log the result inside the closure/callback but can't return the response into a variable. I tried some of the solutions posted already but weren't able to succeed.
Here's my code:
var fcmTokens = [input.fcmToken];
switch(topicType) {
case 'post':
const username = (input.username).toLowerCase();
const userPrefix = Config.get(`setting.topic.user.prefix`);
fcmTokens = Topic.get(`${userPrefix}-${username}`, {AttributesToGet : ['fcmToken']}, function(err,foundTopic) {
var result = foundTopic.attrs.fcmToken;
console.log(result) //Able to log my expected result
return result;
})
console.log(fcmTokens) //undefined
break;
}

I was able to resolve my own issue by installing a library called promisified-vogels as my Model is using a DynamoDB.
From my current code above to this:
let userTopic = await Topic
.getAsync(`${userPrefix}-${username}`,{ConsistentRead: true, AttributesToGet : ['fcmToken']}) //from original function "get" changed to "getAsync"
.then(function(user){
return user.attrs.fcmToken;
})
.catch(function(err){
console.log(err)
});
fcmTokens = userTopic; // i was able to get the list of record im expecting.
Reference Library : https://github.com/servel333/vogels-promisified

Related

I want to return data from dynamodb when the key matches

**I want to return the data key values but it is not working. Please help me. The main concept of this method is when this is invoke dal is the keyword and it fetches that key values from the dynamodb. For that i used global also but not updating that global variable also.
I tried returning the value from the callback, as well as assigning the result to a local variable inside the function and returning that one, but none of those ways actually return the response (they all return undefined or whatever the initial value of the variable result is).**
function getLocation(){
let a=[];
const documentClient = new AWSS.DynamoDB.DocumentClient({region:"us-east-2"});
const params = {
TableName : "ProductLocation1",
Key :{
Product_Name : 'dal'
}
};
documentClient.get(params,(err,data)=>{
if(err){
console.log('error is',err);
}
console.log('data is : ',data);
global.a=Object.keys(data);
});
return global.a;
}
try {
const result = await documentClient.get(params).promise();
} catch (error) {
// handle error
}
You could get the result using the promise & await rather than the callback function. In this way, you don't need to store them in a local variable.

Get return value of module in calling file

my root node file requires a module called q1 (not including all the required libraries as not relevant)
const analyzeSentiment = function(message) {
sentiment.getSentiment(message).then(result => {
return (result.vote === 'positive') ? handlePositive() : handleNegative();
});
}
const handlePositive = function() {
return `That's great, we have an opening next Friday at 3pm. Would that work for you?`;
}
const handleNegative = function() {
return `That's okay. Thanks for you time. If you change your mind, give us a call at (xxx) yyy-zzzz.`;
}
exports.analyzeSentiment = analyzeSentiment;
I call it like this: const message = require('q1').analyzeSentiment('text string');
With console logging I can see that it makes it down into the proper handlePositive or handleNegative methods, but nothing comes back. I've tried a few different ways but can't get it to work. Anyone have any suggestions, or see something blatantly wrong I'm doing? This is my first time working with node.
Your function analyzeSentiment not returning anything (see explanation further down).
Try this:
const analyzeSentiment = function(message) {
return sentiment.getSentiment(message).then(result => {
return (result.vote === 'positive') ? handlePositive() : handleNegative();
});
}
And in your caller:
require('q1').sentimentAnalyzer('text string').then(message => {
// Do your thing with the message here
});
Alternatively, if you are in an async context you can use await on the caller:
const message = await require('q1').sentimentAnalyzer('text string');
You might be wondering why the return (result.vote === ... isn't returning from your analyzeSentiment-function. The reason is that the you are creating an anonymous function with the arrow-expression result => ... in the then-block.

MongoDB returning a null, but query works separately

In a post function, I am trying to retrieve the nth activity of a user (since I have a dropdown that return the index number of the activity). When I run the query
collection.find({'local.email':req.user.local.email},
{'local.activities':{$slice : [currActivity,1]}});
I receive the correct activity object in Robo3T.
But, when I call the same query in Node inside a post function, it returns an undefined.
app.post('/addlog',function(req,res){
var currActivity = req.body.curAct;
var score = req.body.score;
var comment = req.body.reason;
mongoose.connect('mongodb://****:****#ds044907.mlab.com:44907/intraspect',function (err, database) {
if (err)
throw err
else
{
db = database;
var collection = db.collection('users');
var retrievedAct = collection.find({'local.email':req.user.local.email},
{'local.activities':{$slice : [currActivity,1]}}).toArray().then(console.log(retrievedAct));
if (retrievedAct.length > 0) { printjson (retrievedAct[0]); }
console.log(currActivity);
console.log(retrievedAct[0]);
// console.log(req.body.newAct);
collection.update({'local.activities.name':retrievedAct[0]},
{$push: {'local.activities.log' : {
comments: comment,
score: score,
log_time: Date.now()
}}})
.then(function(){
res.redirect('/homepage');
})
.catch(function() {
console.log('Error');
});
}
});
});
I checked that the currActivity variable does infact contain the integer value for the nth activity.
If you want the result of collection.find().toArray(), as specified in the docs, you have two options:
Passing a callback to .toArray() like you did with mongoose.connect()
Using the Promise that it returns if you don't pass a callback
Now you are doing neither of them.
Also, you are mixing callback style and Promises in your code. I recommend you unificate your code. If you are using a Node.js version bigger than 8, using async/await could be nice, it makes it simpler.

Cannot store value inside .get method from npm library 'Sqlite3'

Problem: I cannot get a variable into the correct scope, using the .get function from the nodejs library 'sqlite3'.
Explanation: Even though I have declared the variable 'image_path' in a scope from which it can be returned out of the function, when I assign it a value within the .get method, the scope of image_path appears to change; It is no longer able to be returned from the function 'returnImagePath' as expected.
Aim: I simply want to create a function with which I can query an Sqlite3 database using nodejs and return a value. If there is a better way of doing that then what I am currently trying, I will accept it as an answer.
Example:
var sqlite3 = require('sqlite3');
var dataBaseFile = 'test.db';
var dataBase = new sqlite3.Database(dataBaseFile);
function returnImagePath(id){
var image_path;
dataBase.serialize(function(){
var statementReturnImagePath = dataBase.prepare(`SELECT image_path FROM images WHERE id = ${id}`);
statementReturnImagePath.run();
statementReturnImagePath.finalize();
dataBase.get(`SELECT image_path FROM images WHERE id = 1`, function(error, row){
image_path = row.image_path;
console.log(image_path); //image_path is defined here, and logs as expected
});
dataBase.close();
});
console.log(image_path); //image_path is undefined here
return image_path;
}
var asdf = returnImagePath(1);
console.log(asdf); //this, therefore doesn't work
In the node.js world, you have to understand what is asynchronous function.
If a process requires IO operations, you cannot just return the data from that process, instead you have to "wait" for the data.
We usually achieve this with a callback function.
Here is the example for you,
var sqlite3 = require('sqlite3');
var dataBaseFile = 'test.db';
var dataBase = new sqlite3.Database(dataBaseFile);
//callback is a function which accept (err, data)
function returnImagePath(id, callback){
dataBase.serialize(function(){
dataBase.get('SELECT image_path FROM images WHERE id = ' + id, function(error, row){
if (error) {
//stop and return error if error occurs
return callback(error, null);
}
image_path = row.image_path;
console.log(image_path); //image_path is defined here, and logs as expected
//now you get the image path and return it with callback
callback(null, image_path);
dataBase.close();
});
});
}
returnImagePath(1, function(err, image_path) {
if (err) { //capture error(s)
return console.error(err);
}
console.log(image_path); //now you get the image path
});

return value is null in node.js with mongoose

I am using node.js with mongoose. The problem i am facing is i am getting newModifier1 printed but outside that function the value is null.
Here is my code:
// Find userSchema
newModifier1 = "";
exports.findModifier = function(modifierName){
modifierModel.find({'name' : modifierName},function(err,result){
if(err){
console.log("Error : "+err);
throw err;
}
else{
newModifier1 = result;
// console.log("Modifier is searched successfully : "+newModifier1);
}
console.log("Modifier is searched successfully1 : "+newModifier1);
});
// newModifier1=temp;
return newModifier1; // it takes newModifier1 = "" value here
}
Any ideas what the problem could be?
This is what is happening:
// this is "global" an would be weirdly overwritten
// if function is called multiple times before finishing
newModifier1 = "";
exports.findModifier = function(modifierName){
// TIMESTAMP: 0
modifierModel.find({'name' : modifierName},function(err,result){
// TIMESTAMP: 2
if(err){
console.log("Error : "+err);
throw err;
}
else{
newModifier1 = result;
// console.log("Modifier is searched successfully : "+newModifier1);
}
console.log("Modifier is searched successfully1 : "+newModifier1);
});
// TIMESTAMP: 1
return newModifier1; // it takes newModifier1 = "" value here
}
I added some notes, when what is happening. As you can see and because of the async nature of node.js you return the value before you get a result back from the database.
You need familiarize yourself with the async flow and callback function.
Pass a callback function to findModifier and wait for the database to return a result.
modifierModel.find runs asynchronously and probably findModifier method is returning before the callback of find method executes. Although you see it being printed out what is returned from the method is en empty string anyway. You can use a library like async.

Resources