The following method should query in the conversationCollection for an entry with a given ObjectID.
const mongodb = require('mongodb')
const ObjectID = mongodb.ObjectID
app.get('/getConversations', (req, res) => {
verifyUser(req, res, function(result) {
if(result !== "false") {
for(var i=0; i<result.conversations.length; i++) {
var objectid = new ObjectID(result.conversations[i].toString())
conversationCollection.findOne({_id: objectid}, function(res2) {
console.log(res2.members)
res.end(res2)
})
}
} else {
res.end("Error")
}
})
})
The result object has e.g. following data:
{
// ...
conversations: [ 5ccdc51d22399918b45b33d4,
5ccdc52322399918b45b33d6 ],
// ...
}
The problem is that console.log(res2.members) always throws TypeError: Cannot read property 'members' of null. The query for the findOne-method seams to be wrong. I've tried some variants already:
conversationCollection.findOne({"_id": objectid}, function(res2)
conversationCollection.findOne({_id: new ObjectID(result.conversations[i].toString())}, function(res2)
conversationCollection.findOne({"_id": ew ObjectID(result.conversations[i])}, function(res2)
conversationCollection.findOne({"_id": result.conversations[i]}, function(res2)
Nothing works and every variant produces the same nullpointer-exception.
This is because the res2 holds error data which is null.
findOne function has two params in callback: 1st is error and other is data. either of them is null.
try this:
app.get('/getConversations', (req, res) => {
verifyUser(req, res, function(result) {
if(result !== "false") {
for(var i=0; i<result.conversations.length; i++) {
var objectid = new ObjectID(result.conversations[i].toString())
conversationCollection.findOne({_id: objectid}, function(err,res2) {
console.log(err)
console.log(res2.members)
res.end(res2)
})
}
} else {
res.end("Error")
}
})
})
Related
Below is the piece of code i have written , to get the result but null in response
I am using selectObjectContent api to get the results with the simple SQL query
const bucket = 'myBucketname'
const key = 'file.json.gz'
const query = "SELECT * FROM s3object "
const params = {
Bucket: bucket,
Key: key,
ExpressionType: "SQL",
Expression: query,
InputSerialization: {
CompressionType: "GZIP",
JSON: {
Type: "LINES"
},
},
OutputSerialization: {
JSON: {
RecordDelimiter: ","
}
}
}
s3.selectObjectContent(params,(err, data) => {
if (err) {
console.log(data)
} else {
console.log(err)
}
})
I have found the solution to it. was logging error when getting successfull result/data , so corrected it below. Also i have found the way to read stream buffer data
s3.selectObjectContent(params,(err, data) => {
if (err) {
console.log(err)
} else {
console.log(data)
}
})
const eventStream = data.Payload;
// Read events as they are available
eventStream.on('data', (event) => {
if (event.Records) {
// event.Records.Payload is a buffer containing
// a single record, partial records, or multiple records
var records = event.Records.Payload.toString();
console.log( records )
} else if (event.Stats) {
console.log(`Processed ${event.Stats.Details.BytesProcessed} bytes`);
} else if (event.End) {
console.log('SelectObjectContent completed');
}
I have hapi js server route handler method and it has knexjs select query with limit the result set to 10 per page. but in that same reply need to get the totalPages count too. I included separate function to get the total post count. but 'totalPages' value is not displaying in the json result. Can I know how to get total query count to 'totalPages' variable before execute 'getOperation' method and include that value to 'getOperation' reply section.
server.route({
path: options.basePath + '/posts/byCategory/{category}/list/page/{page}',
method: 'GET',
handler: async (request, reply) => {
const page= request.params.page;
const category = request.params.category;
var soffset=(page-1)+"0";
var offset=Number(soffset);
var totalPages;
totalPages = await server.app.knex('posts').where({
category_english_name: category
}).select().then((results) => {
results.length;
});
const getOperation = server.app.knex('posts').where({
category_english_name: category
}).select().limit(10).offset(offset).then((results) => {
//totalPages=Math.ceil(results.length/10);
if (!results || results.length === 0) {
reply({
error: true,
errMessage: 'No result found',
});
}
reply({
page:page,
dataCount: results.length,
offset:offset,
total_pages: totalPages,
results: results,
});
}).catch((err) => {
reply('server-side error');
console.log(err);
});
}
});```
I found answer for this question.
we need to create a function with return the first query result. then we need to call that function and the returned value should be assigned to const variable in handle function. then we can add the first query result to our reply.
function with parameter to execute first query
function getAllPageCount(category) {
return server.app.knex('posts').where({
category_english_name: category
}).select().then((results) => {
return results.length;
});
};
Then call that function before second query in handler
server.route({
path: options.basePath + '/posts/byCategory/{category}/list/page/{page}',
method: 'GET',
handler: async (request, reply) => {
const page= request.params.page;
const category = request.params.category;
var soffset=(page-1)+"0";
var offset=Number(soffset);
var tot;
const pageCount = await getAllPageCount(category).catch((err) => { throw err })
console.log("pageCount "+pageCount);
const getOperation = server.app.knex('posts').where({
category_english_name: category
}).select().limit(10).offset(offset).then((results) => {
//totalPages=Math.ceil(results.length/10);
if (!results || results.length === 0) {
reply({
error: true,
errMessage: 'No result found',
});
}
reply({
page:page,
dataCount: results.length,
offset:offset,
total_pages: pageCount,
results: results,
});
}).catch((err) => {
reply('server-side error');
console.log(err);
});
}
});
I am trying to use the node.js Google API to iterate over my email messages
const google = require('googleapis');
The problem is that I keep getting the same email messages and every response contains the exact same nextPageToken.
I also noticed that trying to control the maxResults parameter has no effect. I tried to add them to the options object and the query objects and it had no effect in either way.
function listThreads(auth, nextPageToken) {
const gmail = google.gmail('v1');
const query = {
auth : auth,
userId: 'me',
q: ""
};
const options = {maxResults: 20}
if (nextPageToken) {
query.pageToken = nextPageToken;
}
gmail.users.messages.list(query, options, function(err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
const messages = response.messages;
if (messages.length === 0) {
console.log('No threads found.');
} else {
for (let i = 0; i < messages.length; i++) {
const message = messages[i];
gmail.users.messages.get({
auth : auth,
userId: 'me',
id : message.id
}, function(err, response) {
if (err) {
logger.error("Failed to get email", err);
} else {
const parser = new Parser();
parser.parse(response.payload, response.labelIds);
}
});
}
}
if (response.nextPageToken) {
listThreads(auth, response.nextPageToken);
}
});
}
What am I doing wrong?
In my database.js I have
var Mysql = require('Mysql');
var Jwt = require('jsonwebtoken');
var bcrypt = require('bcrypt');
var supersecretkey = 'JMDub_Super_Secret_key';
var config = require('./config');
var signupErrors = require('./Signuperrors.js');
var sucessMsg = require('./SucessMessages.js');
var App_errors = require('./error.js');
var query = require('./queryDB.js');
var connection = Mysql.createConnection({
"host": "******",
"user": "****",
"password": "***",
"database": "***"
});
connection.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
console.log('connected as id ' + connection.threadId);
});
//Sign Up Methods
var createUser = function createwithCredentails(post,callback) {
bcrypt.hash(post.password, 10, function(err, hash){
//console.log('Cache Hash : +',hash);
var createUserQuery = connection.query('INSERT INTO users SET ?',{"email":post.email,"password":hash,"username":post.username},function(err,result){
if (err) {
if (err.code == 'ER_DUP_ENTRY') {
//console.log(err.code);
callback(signupErrors.error_5000);
}
else callback(App_errors.error_1003);
}
if (result) {
callback(sucessMsg.success_signup);
}
});
});
}
//connection.query('SELECT * FROM Users Where Username = '' AND Password = ''');
var validateUser = function ValidateUserWithUserNameAndPassword(post,callback) {
var UserCheckQuery = connection.query('SELECT * FROM users WHERE email="'+post.email+'"',function(err, results, fields) {
if (err){
console.log(err);
callback(App_errors.error_1000);
}
if (results.length == 1) {
//console.log(results[0].password,post.password);
var givenPassword = post.password;
var DBhash = results[0].password;
bcrypt.compare(givenPassword, DBhash,function(err, res) {
if (res) {
console.log('Password matched');
var token = Jwt.sign({"email":post.email,"username":post.username},supersecretkey, {
expiresIn: 60*60*5 // expires in 5 hours
});
callback({
message:{
"success":1,
"description":"sucessfully logged in - please cache the token for any queries in future",
"environment":"test",
"errorCode":null
},
"token":token
});
}
if (!res) {
console.log('password doesnt match');
callback(signupErrors.error_6000);
}
if (err) {
console.log('Error Comparing Passwords');
callback(App_errors.error_1004);
}
});
}
else{
callback(signupErrors.error_6000);
}
});
};
var isauthenticate = function isauthenticated(post,route,callback) {
if (post.headers.token) {
Jwt.verify(post.headers.token, supersecretkey, function(err, decoded) {
if (decoded) {
//console.log(decoded);
//From this part the user is Sucessully Authenticated and autherization params can be extracted from token if required
//Write Business Logic in future as per the requirement
//Operation 1 - Update Profile
//Profile Details consists of {1.first name 2.last name 3. profile pictur(base 64 encoded) 4.further settings in future that can be added to DB if required}
if (route == '/update-profile') {
query.updateProfile(connection,decoded.email,post.body,function(response) {
callback(response);
});
}
//callback({"message":"is a valid token"});
}
if (decoded == null) {
console.log('is not a valid token');
//callback(App_errors.error_1000);
}
if (err) {
console.log('error verifying token');
callback(App_errors.error_1000);
}
});
}
else{
callback(App_errors.error_1001);
}
};
module.exports = {
validateUser:validateUser,
createUser:createUser,
isauthenticate:isauthenticate,
connection:connection
}
I am exporting connection object to queryDB.js file. But when I try to log the exported connection object I get undefined object. Why is this happening?
When I pass connection object as function argument, everything works fine. Not sure why?
below is queryDB.js file
var errors = require('./error.js')
var Dbconnection = require('./Database.js').connection;
var updateProfile = function profiledata(connection,email,data,callback) {
console.log(Dbconnection);
if ((!data)|| (Object.keys(data).length < 1)) {
//console.log(data);
callback(errors.error_1001);
}
else{
callback({"message":"update Sucesss"});
//console.log(connection);
//var updateData = mapProfileDataTomodel(data);
//console.log(updateData);
connection.query('SELECT * FROM users WHERE email = "'+email+'"',function(err, result,feilds) {
if (err) throw err;
if (result) {
console.log(result);
}
});
}
}
var mapProfileDataTomodel = function mapProfileDataTomodel(data) {
var profileDataModel = {};
for (var key in data) {
//console.log('looping and mapping data');
if (data.firstname) {
profileDataModel.firstname = data.firstname;
}
if (data.lastname) {
profileDataModel.lastname = data.lastname;
}
if (data.profilepic) {
profileDataModel.profilepic = data.profilepic;
}
}
return profileDataModel;
}
module.exports = {
updateProfile:updateProfile
}
I have commented out connection object log via function arguments.
So, Why I am unable to get the connection object that is exported? But I used the same exported connection object in my app.js file. It did work fine there.
I m doing a javascript function using mongoose to find a group which contains a list of users emails, that part works perfectly. After I want to find each user of the list and add the new group name instead of the old group name, I don't know why, but it doesn't work, the function returns me the group before doing the for loop, and the users are not modified.
Here is my user model :
var userSchema = mongoose.Schema({
local : {
email : String,
password : String,
}
groups : { type: [String], default: []}
});
And here my Group model :
var groupSchema = mongoose.Schema({
title : String,
creator : String,
listOfUsers : { type: [String], default: []}
});
And here my function :
Group.findOne({ '_id': groupId}, function (error, group){
var oldTitle = group.title;
group.title = req.body.title;
group.save();
if(error){
throw (error)
}
for(var i = 0; i < group.listOfUsers.length;i++){
User.findOne({'local.email': group.listOfUsers[i]}, function(error,user){
if(error){
throw (error)
}
for(var j=0;j<user.groups.length;j++){
if(user.groups[j] == oldTitle){
user.groups[j] = group.title;
user.save();
}
}
});
}
return res.json(group);
you can use async to fix the callback problem
async.waterfall(
[
function (callback) {
Group.findOne({
'_id': groupId
}, function (error, group) {
if (error) {
throw (error)
} else {
callback(null, group);
}
})
},
function (group, callback) {
for (var i = 0; i < group.listOfUsers.length; i++) {
User.findOne({
'local.email': group.listOfUsers[i]
}, function (error, user) {
if (error) {
throw (error)
} else {
callback(null, user, group);
}
});
}
},
function (user, group, callback) {
var oldTitle = group.title;
group.title = req.body.title;
for (var j = 0; j < user.groups.length; j++) {
if (user.groups[j] == oldTitle) {
user.groups[j] = group.title;
user.save();
}
}
callback(null, 'done');
}
],
function (err, result) {
console.info("4");
console.info(err);
console.info(result);
});
forgive me if i made any mistake, it is always hard to write code without data, i hope you will understand how i wanted to solve.
and don't forget
var async = require('async');
at the beginning
You should do user.save() only after for loop is finished. I updated for loops with forEach which I feel more comfortable to use.
Group.findbyId(groupId, function(err, group) {
var oldTitle = group.title;
group.title = req.body.title;
if (group.save()) {
listOfUsers.forEach(function(groupUser) {
User.findOne({'local.email' : groupUser}, function (err, user) {
if(user) {
user.group.forEach(function(userGroup) {
if (userGroup == oldTitle) {
userGroup = group.title;
}
})
user.save();
}
});
});
res.json(group);
} else {
res.status(400).json({messsage: 'Error while saving group!'});
}
});