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);
Related
I'm having a problem updating an object field with a key and a value on the user instance. The code runs successfully by saving but does not update the key on the object. Here is the code that I'm running
let query = new Parse.Query(Parse.User);
app.post("/saveListName", function (req, res) {
query.get(req.body.userObjectId, {
success: function (user) {
console.log(user);
user.set("list.foo", "Hello world"); //this is what I'm updating
user.save(null, {
useMasterKey: true
}).then(function (res) {
console.log("User saved");
console.log(res);
}).catch(function (err) {
console.log(err);
})
res.send(true);
},
error: function (err) {
console.log(err);
res.send(false);
}
})
})
foo is the key I'm trying to update on the list object. And I want to dynamically add new keys to the list object but not only one key. Please, I need help with this. I'm wondering if this feature(dynamically appending/removing fields on an object) is even supported in parse because going through documentation http://docs.parseplatform.org/js/guide/#updating-objects and I have not seen anything like that. Thanks
So I have a function that when you pass a username as an argument it queries a MongoDB database and returns the document containing that username. So in the function, I check to see if the document exists containing the username, and if it doesn't I return the document that has an empty string as the username. So kind of like, return default if doesn't exist. So I assume that if it doesn't find a matching document it returns an undefined object.
Ideally, I want a function that when called will either return a default document retrieved from a database when the username doesn't exist or return the corresponding document for the username passed as an argument. Maybe the problems are trying to read or return variables before they exist because of the asynchronous nature of the calls.
I really don't think major restructuring of the code is a good idea, because I'm trying to work with three asynchronous libraries and connect them all together. I have multiple asynchronous classes in recursive processing functions.
getContext(username = '') {
const MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/tc-db', function (err, db) {
if (err) {
console.log(err);
} else {
db.collection('chatters').findOne({ username: username }, function (err, results) {
if (err) {
throw err;
} else if (results === undefined) {
db.collection('chatters').findOne({ username: '' }, function (err, results) {
console.log('Notifier');
console.log('Get if Null: ' + JSON.stringify(results));
return JSON.stringify(results.context);
});
} else {
console.log('Notifier 2');
return JSON.stringify(results.context);
}
});
}
});
}
The actual error I'm getting alot when running the function, especially with a username that doesn't exist in the database is "Can't read property 'context' of null". Thank you guys so much for any help you can offer.
I am using Node.js (noob in BDD). In my controller I have a function like so:
var getUser = function(username, done) {
console.log('prints');
User.findOne({
'local.username': username
}, function (err, user) {
console.log('doesn"t print');
if (err) {
return done('Oops, server error!', null);
} else {
return done(null, user);
}
});
};
I am using Mocha and described a test block like so:
describe('can be created only using a web interface', function () {
describe('The user name should:', function () {
it("be a valid email", function () {
assert(common.isValidEmail(fakeuser.local.username));
});
it("not already exist in the database", function () {
userController.getUser(fakeuser.local.username, function (err, user) {
log.info('The user name is', user);
//I would like to assert here. But user is always undefined.
}());
});
});
});
It seems like User.findOne is not working the way I expect it to since the test passes no matter what and the code inside doesn't even get executed. What am I missing?
NB: Calling the same function in other parts of the code works just fine.
EDIT
The project is accessible here: https://github.com/attosol/nodeseed
The documentation (and project) is far from complete. Just do an npm install, and npm start followed by starting up your MongoDB (it will use the DB - nodeseed). Just signup using any valid email and find the activation URL in your log files.
You'll have to write something to compare against
it("not already exist in the database", function(done){
var wasCalled = false;
userController.getUser('my#email.com', function(err, user){
console.log('doesn"t print');
wasCalled = true;
});
expect(wasCalled).toBe(true);
});
I have to try to fetch a field value from MongoDB using Node.js. But it shows me undefined in my console. My requirement is to print the data in the console or browser from MongoDB using Node.js.
1). This is my node js
this.levelChange = function(req, res, next){
try{
var query = {'level_num':2};
QuizLevel.find(query,function(err,data){
var a = data.min_score;
console.log(a);
res.send(a);
});
}catch(err){
console.log("Error");
return next(err);
}
};
2). This is my js-schema
{
_id:{type:String},
age:{type:Number},
level_num:{type:String},
min_score:{type:String},
max_questions:{type:String}
}
3).This is my console output
undefined
4). This is my JSON data
{
"age":5,
"level_num":1,
"min_score":10,
"max_questions":30
},
{
"age":5,
"level_num":2,
"min_score":12,
"max_questions":33
}
Simply use findOne(find return an array of document) with a project field(return only desired fields).
And don't forget to check the err field !
try{
var query = {'level_num':2};
QuizLevel.findOne(query,{min_score: 1}, function(err,data){
if(err || !data)
{
console.log(err);
return next(err);
}
else
{
var a = data.min_score;
console.log(a);
res.send(a);
}
});
}catch(err){
console.log("Error");
return next(err);
}
I might be incorrect but it looks like you're trying to access object property while the result is a collection, see:
data.min_score // => [{ ... }, { ... }].min_score
vs
data[0].min_score
What you want to achieve is something like:
var scores = data.map((function (item) {
return item.min_score;
});
console.log(scores);
You can always check the type of result with console.log(typeof data) or simply write console.log(data), sometimes console.log(Object.keys(data)) come in handy as well for simple debugging not to mention node-inspector.
I've got this error when trying to POST
> process.nextTick(function() { throw err; });
> ^
>
> TypeError: first argument must be a string or Buffer
> at ServerResponse.OutgoingMessage.end (_http_outgoing.js:524:11)
Errors shows that something's wrong with utils and cursor both from mongodb module, but what are they?
Everything works nice on GET but brakes on POST (postman and passing as text {"name":"Computer","price":2500}) - i cannot trace which module or instance is braking the code.
This is my conn with db:
// Our primary interface for the MongoDB instance
var MongoClient = require('mongodb').MongoClient;
// Used in order verify correct return values
var assert = require('assert');
var connect = function (databaseName, callBack) {
var url = 'mongodb://localhost:27017/' + databaseName;
MongoClient.connect(url,
function (error, database) {
assert.equal(null, error);
console.log("Succesfully connected to MongoDB instance!");
callBack(database);
});
};
exports.find = function (databaseName, collectionName, query, callback) {
connect(databaseName, function (database) {
var collection = database.collection(collectionName);
collection.find(query).toArray(
// Callback method
function (err, documents) {
// Make sure nothing went wrong
assert.equal(err, null);
// Print all the documents which we found, if any
console.log("MongoDB returned the following documents:");
console.dir(documents)
callback(err, documents);
// Close the database connection to free resources
database.close();
})
})
};
exports.insert = function (databaseName, collectionName, object, callback) {
connect(databaseName, function (database) {
var collection = database.collection(collectionName);
collection.insert(document, {w: 1}, function (err, documents) {
console.log("Added a new document");
console.log(documents[0]);
callback(err, documents[0]);
});
})
};
exports.remove = function (databaseName, collectionName, object, callback) {
connect(databaseName, function (database) {
var collection = database.collection(collectionName);
collection.remove(object, function (err, result) {
callback(err, result);
database.close();
});
})
};
The issue is actually pretty straightforward, so I'm surprised that you're not getting a better error message.
In your code:
collection.insert(document, {w: 1}, function (err, documents) {
console.log("Added a new document");
console.log(documents[0]); // I expect this to log undefined
callback(err, documents[0]);
});
The second argument passed into the collection.insert callback is actually a results object, not the documents that were inserted. So, documents[0] ends up being undefined because it's not an array of documents. Thus, when you trying to send undefined as a response, it's failing.
If you intention is to pass the newly created documents, you're going to have to use the result object to get the _id and attach it to the document you inserted.
As a side note, I would consider keeping a connection open to your database rather than creating a new connection every time you want to talk with Mongo.