I am puzzled as to where or how the below function call for .insert() works? I've tried googling for javascript insert functions and looked through the entire directory for a defined insert function but there's nothing. Here is the code:
router.post('/new', function(req, res) {
var username = req.session.username;
var nextNote, note;
var reportInserted = function(err, notesInserted) {
if (err) {
res.redirect("/notes?error=Could not create a new note");
} else {
res.redirect("/edit/" + notesInserted[0]._id);
}
}
if (username) {
newNote = {title: "Untitled",
owner: username,
content: "No content"};
notesCollection.insert(newNote, reportInserted);
} else {
res.redirect("/?error=Not Logged In");
}
});
I'm going out on a limb, and downvote me if you have to, but if you have no familiarity with what you see and it's not in the current directory, it's part of a pre-existing Node module. Idiomatically, chances are much better than 50-50 that it is:
http://mongodb.github.io/node-mongodb-native/api-generated/collection.html
The function right below the constructor is indeed insert and MongoDB is a very reasonable tool for a collection of notes, given that it's a document-oriented dynamic database.
Related
I did a couple of projects with node.js and I'm aware of the async behaviour and that one should usually use callback functions, etc. But one thing that bothers me ist the following.
I'm developing an Alexa skill and I have a function that handles the User intent:
'MyFunction': function() {
var toSay = ""; // Holds info what Alexa says
// Lot of checks and calculations what needs to be said by Alexa (nothing special)
if(xyz) {
toSay = "XYZ";
}else if(abc) {
toSay = "ABC";
}else{
toSay = "Something";
}
// Here is the "tricky" party
if(someSpecialEvent) {
toSay += " "+askDatabaseForInput(); // Add some information from database to string
}
this.emit(':ask', toSay, this.t('REPROMT_SPEECH')); // Gives the Info to Alexa (code execution stops here)
}
As mentioned in the code, there is some code which is usually used to find out what the output to Alexa should be.
Only on rare events, "someSpecialEvent", I need to query the database and add information to the String "toSay".
Querying the DB would look something like:
function askDatabaseForInput() { // The function to query the DB
var params = {
TableName: "MyTable",
OtherValues: "..."
};
// Do the Query
docClient.query(params, function(err, data) {
// Of course here are some checks if everything worked, etc.
var item = data.Items[0];
return item; // Item SHOULD be returned
});
return infoFromDocClient; // Which is, of course not possible
}
Now I know, that in the first function "'MyFunction'" I could just pass the variable "toSay" down to the DB Function and then to the DB Query and if everything is fine, I would do the "this.emit()" in the DB Query function. But for me, this looks very dirty and not much reusable.
So is there a way I can use "askDatabaseForInput()" to return DB information and just add it to a String? This means making the asynchronous call synchronous.
Making a synchronous call wouldn't affect the user experience, as the code isn't doing anything else anyway and it just creates the String and is (maybe) waiting for DB input.
Thanks for any help.
So you could do 2 things:
Like the person who commented says you could use a callback:
function askDatabaseForInput(callback) {
var params = {
TableName: "MyTable",
OtherValues: "..."
};
docClient.query(params, function(err, data) {
if (err) {
callback(err, null)
} else {
var item = data.Items[0];
callback(null, item);
}
});
}
or you could use promises:
function askDatabaseForInput() {
var params = {
TableName: "MyTable",
OtherValues: "..."
};
return new Promise(function (resolve, reject) {
docClient.query(params, function(err, data) {
if (err) {
reject(err)
} else {
var item = data.Items[0];
resolve(item);
}
});
});
}
you can then either put a function in where you call askDatabaseForInput or do askDatabaseForInput.then(....).
In the function or the .then you would add what you retrieved from the database to the variable toSay
hope this helps
I'm trying to access a variable named city in the Meteor Accounts.onCreateUser user creation function and have not been successful in my attempts to do so. I have tried to return city at the end of the HTTP.get call and have also tried creating the city var outside of HTTP.get and simply setting city without using var but none of these things seems to have worked. When console.log(city) runs it does accurately output the desired information so this variable must not be the issue. If I am making a nube mistake forgive me.
Accounts.onCreateUser( function (options, user) {
if (options.profile) {
options.profile.picturelrg = "http://graph.facebook.com/" + user.services.facebook.id + "/picture/?type=large";
user.profile = options.profile;
options.profile.picturesm = "http://graph.facebook.com/" + user.services.facebook.id + "/picture/?type=small";
options.profile.messenger = "https://www.messenger.com/t/" + user.services.facebook.id;
HTTP.get("http://ipinfo.io", function (error, result) {
var place = JSON.parse(result.content);
var city = place.city;
console.log(city);
});
options.profile.city = city;
}
return user;
});
The technically correct repose to this is that you need to use the synchronous version of HTTP.get. See the docs and this question for examples.
However there's a more fundamental issue: you're trying to grab the user's location data but onCreateUser only runs on the server. So even if you do solve this problem, you'll end up with the same data in each user's profile. You'll need to run the get on the client and update via a method. Try something like this:
Accounts.createUser(options, function(err) {
if (!err) {
HTTP.get(..., function(err, result) {
var city = ...;
var place = ...;
Meteor.call('updateProfileWithCityandPlace', city, place);
});
}
});
Meteor.methods({
updateProfileWithCityandPlace: function(city, place) {
check(city, String);
check(place, String);
Meteor.users.update(this.userId, {
$set: {'profile.city': city, 'profile.place': place}
});
}
});
I am writting a little app to calculate and keep track of how much gas my car is using. But i have a problem with my facade.
When i am trying to add some new details to my database, i only get a empty object somehow.
I know the problem is in my facade, and maybe some of you can see what it is.
(Don't worry about the name of the method)
function addTitle (kilometer, liter, kmLiter, callback){
var data = {
kilometer: kilometer,
liter: liter,
kmLiter: kmLiter
}
detail.create({details:data}, function(err, result){
if(err)
return callback(err);
else
callback(null, result);
});
};
And this is the model of the DB
var DetailSchema = mongoose.Schema({
details:[{
kilometer: String,
liter: String,
kmLiter: String}
]
});
mongoose.model('Details', DetailSchema, "details");
Anybody that can find the error?
Assuming your schema definition of details being an array is what you want, you need to also make details an array when you create new docs.
So your function should change to:
function addTitle (kilometer, liter, kmLiter, callback){
var data = {
kilometer: kilometer,
liter: liter,
kmLiter: kmLiter
}
detail.create({details: [data]}, callback);
}
I am using sockets with mongodb, for a user who is trying to create a new name, I need to check all the models in the database to see if it exists.
I am doing it all wrong, basically I am trying to do something like this.
var allUsers = [];
models.Message.find({}, function(err, data) {
for(var i=0; i < data.length; i++) {
allUsers.push(data[i].username);
}
});
console.log(allUsers)
I'm sitting here struggling even getting the allUsers out of the function, and I am thinking this is not even the best way to do this. With allUsers I was just going to check to see if the new username existed in the array.
So to futher extend what I am doing here is some socket.io code. I was going to run some validation like this if I could get the allUsers to work.
socket.on('new user', function (data, callback) {
if(data in allUsers) {
callback(false);
} else {
callback(true);
socket.userName = data;
socket.connected = true;
users[socket.userName] = socket;
io.sockets.emit('user name', {usernames: users[socket.userName].userName, connected: users[socket.userName].connected});
}
});
But without it working, this is no good. So my question is with what I have provided (socket.io, mongodb) how do I get all the models and validate if a new user which is passed in data exists in the database?
models.Message.find is async, the result of the async operation is only available when the async operation has finished.so console.log(allUsers) will always yield an empty array.
should be something like (pseudo js code):
socket.on('new user', function (data, callback) {
models.User.findOne({username:data.username},function(err,user){
if(err){/*deal with error here */}
else if(user){/*username already taken
respond with appropriate socket message here */
socket.emit('user name already taken',{somemessage});
}
else{/* user with username not found */
/*create new user into database then emit socket message */
var user = new models.User(data);
user.save(function(err,user){
socket.emit('user name',{somemessage});
})
}
});
});
I am currently involved helping out on a project which involves using the Geddy js framework, which it is my first time using. I am currently trying to fix the create method inside a model for users. Here is the code below:
this.create = function (req, resp, params) {
var self = this
, user = geddy.model.User.create(params);
//need to ensure that the user agrees with the terms and conditions.
// Non-blocking uniqueness checks are hard
geddy.model.User.first({username: user.username}, function(err, data) {
if (data) {
params.errors = {
username: 'This username is already in use.'
};
//self.transfer('add');
}
else {
if (user.isValid()) {
user.password = cryptPass(user.password);
user.suburb = "";
user.state = "";
user.postcode = "";
}
user.save(function(err, data) {
if (err) {
params.errors = err;
self.transfer('add');
}
else {
// setup e-mail data with unicode symbols
var mailOptions = {
from: "App ✔ <hello#app.com>", // sender address
to: user.email, // list of receivers
subject: user.username + " Thank you for Signing Up ✔", // Subject line
text: "Please log in and start shopping! ✔", // plaintext body
html: "<b>Please log in and start shopping!✔</b>" // html body
}
smtpTransport.sendMail(mailOptions, function(error, response){
if(error){
console.log(error);
}else{
console.log("Message sent: " + response.message);
}
// if you don't want to use this transport object anymore, uncomment following line
smtpTransport.close(); // shut down the connection pool, no more messages
});
self.redirect({controller: self.name});
}
});
}
});
};
If you look in the code there is apparently a check to see if the so-called user is valid like so: if (user.isValid()) {
user.password = cryptPass(user.password);
user.suburb = "";
user.state = "";
user.postcode = "";
}
The proceeds on to 'save' regardless whether or not the user is valid. I'm thinking why is the code this way? It sounds nonsensical. I asked the original developer who was on the project about it and he said the model was apparently generated when he created the project.
So in bit of a confused state, if anyone can tell me why the save method is outside the if statement in the first place? Is it something the original creators of Geddy intended? or is really nonsensical and I should change it?
Thanks.
Geddy's save() call will error out if the data is invalid (unless force flag is set, which it isn't). It uses the same isValid() call actually. So, looks like what you have here is just someone's way to have a single error handler for all the error cases.
For user.password being set with crypted data only if the data looks valid, I'm guessing this is simply to make 'must be set' type of validation to work. Chances are that even with an empty password, the crypted string would be otherwise counted as set.