Node.js Facebook API - javascript

I am new to Node.js and I am having difficulties. I just wanted someone to explain where I am going wrong. I am trying to get stats from my Facebook chats and I wanted to used this API call. This is the basic code I have written.
var login = require("facebook-chat-api");
login({email: "Email", password: "Password"}, function callback (err, api) {
if(err) return console.error(err);
var threadID = chatNo;
output = api.getThreadInfo(threadNo)
console.log(output)
});
When I run this on Node.js the output is "undefined", I cant tell if its because the API call didn't work, or because I am trying to output it incorrectly. Any help would be greatly appreciated.
Output of Node.js

You should be using the callback of getThreadInfo like this
login({email: "Email", password: "Password"}, function callback (err, api) {
if(err) return console.error(err);
var threadID = chatNo;
api.getThreadInfo(threadID, function (err, info) {
console.log(err, info);
});
});

Related

Mongoose: Understanding Callbacks vs Async/Await

I am trying to understand a callbacks in mongoose. I really just want to clarify my understanding so I can be sure I am on the right track.
I understanding using async/await to do queries in mongodb using mongoose. For example, the following code will get a user from my database, assuming my model "User" is set up correctly.
const getUser = async () => {
const user = await User.find({username: "John"})
return user
}
Here is my problem. I am working through the odin project and I have came across a section where callbacks are used instead of async/await. I have read some of the mongoose documentation regarding the matter without any luck.
Here is an example I am working with:
passport.use(
new LocalStrategy((username, password, done) => {
User.findOne({username: username}, (err, user) => {
if (err) {
return done(err)
}
if (!user) {
return done(null, false, {message:"Incorrect Username"})
}
if (user.password !== password) {
return done(null, false, {message: "Incorrect password"})
}
return done(null, user)
})
})
)
I understand most of what is going on here, but I do not understand how this is able to function without the use of async/await. I am looking specifically at the line:
User.findOne({username: username}, (err, user) => {callback})
My guess is that the database is queried, and if the user is found the data from the query is stored in the parameter "user."
If the query fails and no data is returned, then user becomes null and our err parameter will contain a message.
Is this correct?
You can use simple concept
async getUserList(){
try{
const users = User.findOne({username: username});
return users;
}catch(error){
throw error;
}
}
call function anywhere
console.log(getUserList());

How do you connect to RDS using lambda and should I be putting queries in there?

My first question is about approach. is this the correct way?
I have a react frontend, I make a call to API gateway => this triggers lambda => lambda makes a DB query => returns to API Gateway => react
secondly, my question is how
I have this lambda code:
var pool = mysql.createPool({
host : RDSINSTANCE,
user : USER,
password : PASSWORD,
database : DBNAME
});
exports.handler = (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false
pool.getConnection(function(err, connection) {
connection.query('SELECT * FROM exercises', function (error, results, fields) {
connection.release();
if (error) context.fail(error)
else context.succeed(null, results[0])
});
})
}
I can confirm when I changed the code to be locally node compliant, it correctly returned me the row I was after, so the RDS is setup correctly as is the javascript code.
however, my lambda is timing out
I added this line: context.callbackWaitsForEmptyEventLoop = false as a few people said that was an issue. however, still timing out
I have also tried using callback instead of context. but to no avail
what am I doing wrong?
The flow from API Gateway to Lambda is the correct way.
I advise to use callback instead of context for passing information back to the caller as that is the officially documented way to do it. 1
You should consider that the Lambda may have failed to obtain a connection object from the pool and handle that scenario.
exports.handler = (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false;
pool.getConnection(function(err, connection) {
if (err)
callback(err);
connection.query('SELECT * FROM exercises', function (error, results, fields) {
connection.release();
if (error) callback(error);
else callback(null, results[0]);
});
});
}

Pass variable to callback - nodejs

I'm creating a simple Messenger bot, using unofficial Facebook Chat API (https://github.com/Schmavery/facebook-chat-api) and Node.js.
For now, I'm working on sending messages to specific users, on a specific time. Here's part of my code:
if(msgdate.getTime() <= currdate.getTime()){
console.log(alarms[i].message);
// output: test
api.getUserID(alarms[i].user, (err, users) => {
if(err) return console.error(err);
api.sendMessage(alarms[i].message, users[0].userID);
// TypeError: Cannot read property 'message' of undefined
});
}
And, my question is: how could I pass alarms array to this callback, so I'd be able to send message to a specific user?
Looks like that you change i variable somewhere, and because of that when callback is called alarms[i] is undefined. You need to store alarms[i] in a new variable and use it in callback:
let alarm = alarms[i];
api.getUserID(alarm.user, (err, users) => {
if(err) {
return console.error(err);
}
api.sendMessage(alarm.message, users[0].userID);
});
Appear that you are using for loop outside. Try pass your var that way:
var alarm = alarm[i];
(function (alarm) {
if(msgdate.getTime() <= currdate.getTime()){
console.log(alarm.message);
// output: test
api.getUserID(alarm.user, (err, users) => {
if(err) return console.error(err);
api.sendMessage(alarm.message, users[0].userID);
// TypeError: Cannot read property 'message' of undefined
});
})(alarm);
Maybe you need to pass other vars too. Just put a comma and other var, example:
(function (alarm, user){
// your code here
})(alarm, user);

Nodejs variable prints on console but not on the view

the code is this
module.exports = {
index: function (req, res, next) {
//get an array of all users in user collection
Notification.find(function foundNotification(err, notifications) {
if (err) return next(err);
var elusuario=[];
User.findOne(2, function foundUser (err, user) {
if (err) return next(err);
if (!user) return next();
console.log(user);
console.log("----------------------------");
elusuario = user;
console.log(elusuario);
});
res.view({
notifications: notifications,
elusuario: elusuario
});
})
}
};
That is the controller and in the console prints elusuario good but in the view the user hasn't values. why?
i think is something is something related to the globals variables. but i dont know
thanks
EDIT
all right so the method is async. what im trying to do is find the notifications and the user by her user.id and get the user.name so what if i do this
module.exports = {
index: function (req, res, next) {
//get an array of all users in user collection
Notification.find(function foundNotification(err, notifications) {
if (err) return next(err);
User.find(function foundUser (err, users) {
if (err) return next(err);
var usuarios_locotes = [];
_.each(notifications, function (notification) {
_.each(users, function (user) {
if(notification.token_user==user.token){
console.log(user.token);
usuarios_locotes.push(user);
console.log(usuarios_locotes);
};
});
});
res.view({
notifications: notifications,
users: usuarios_locotes
});
});
})
}
};
it still not working? the __.each is an async funtion to?
sorry for all this maybe stupid questions
The method findOne of User object runs asynchronously. Because of this, you are rendering the view before the findOne returns the user object.
If you put a console.log before the render.view, it'll print the output before the console.log inner findOne method.
When the code is running, the function foundNotification is not executed before you call the res.view. My advice for you is read about Promises.
You can change your code as below to work:
function (req, res, next) {
//get an array of all users in user collection
Notification.find(function foundNotification(err, notifications) {
if (err) return next(err);
var elusuario=[];
User.findOne(2, function foundUser (err, user) {
if (err) return next(err);
if (!user) return next();
console.log(user);
console.log("----------------------------");
elusuario = user;
console.log(elusuario);
res.view({
notifications: notifications,
elusuario: elusuario
});
});
});
}
the findOne Method is an asynchrone method,so it's executed without provinding the res.view with the appropriate data
try to wrap the whole logic in the same function, it may look ugly but it ll do the thing for now
All right so.. first really thanks to everybody. I solve this shit.
I know this is not the right way to do this but it works, so for my proposes it's fine.
the problem after the EDIT was that in the view I'm trying to write an object with parameters but what I've was sending was vector of vector so changing this line:
usuarios_locotes.push(new Object(users[h]));
I can send a vector of objects.
So.. anyway thanks cause later i will change my code to do it better and efficient
This was my first post so sorry for not read the first steps of how to use this haha cause i think i have been make a lot of mistakes.
And sorry for my English :C

Issue with executing prepared statement in Node JS with ibm_db module

I am new to NodeJS technology, while working on nodejs project, I got below issue.
I have implemented ibm_db module (to establish DB2 connection), and using "prepared statements" to execute 'SELECT' queries. Below query is executed without errors but console.log(result) is giving result as {fetchMode : 4}, but I am expecting COLUMN_1 results here. Can someone tell me if I am missing anything here.
db.prepare('SELECT COLUMN_1 FROM TABLE_A WHERE COLUMN_2=?', function(err, stmt){
if(err){
console.log(err);
}
stmt.execute(['CA'], function(err, result){
console.log(result);
});
});
Using an extra fetch inside of execute callback makes it possible for me to see the correct and wanted result of the query statement.
Here an example:
db.prepare('SELECT COLUMN_1 FROM TABLE_A WHERE COLUMN_2=?', function(err, stmt){
if(err){
console.log(err);
}
stmt.execute(['CA'], function(err, result){
result.fetch(function (err, data) {
if (err) {
console.error(err);
}
console.log(JSON.stringify(data));
result.closeSync();
});
});
});
The following site gave me the hint: https://groups.google.com/d/msg/node-ibm_db/AhZeeN6jFTM/MrRXSIW3DQAJ

Categories

Resources