Aws lambda supports mongoose middleware? - mongodb

Does AWS lambda supports mongoose middleware, I'm using .pre() to check data exists on save.
here is my function call for save
res = new cModel();
res.pre('save', function (next) {
cModel.find({name: company.name}, function (err, docs) {
if (!docs.length){
next();
}else{
console.log('company name exists: ',company.name);
next(new Error("Company Name exists!"));
}
});
}) ;
this is my function call to update
company_model.companySchema.pre('update', function (next) {
try {
cModel.find({ name: { $regex: new RegExp(`^${this.getFilter().name}$` , 'i') }}, function (err, docs) {
try {
if (!docs.length) {
next();
} else {
console.log('company name exists: ', this.getFilter().name);
next(new Error("Company Name exists!"));
}
} catch (e) {
console.error('error in cModel.find: ' + e.message);
}
});
} catch (e) {
console.error('error in pre save : ' + e.message)
}
});

eInside a pre('save',... hook, the reference to the current document is found under this. Here I've replaced company with this in your example.
const schema = new mongoose.Schema({})
schema.pre('save', function (next) {
cModel.find({name: this.name}, function (err, docs) {
if (!docs.length){
next();
} else {
console.log('company name exists: ', this.name);
next(new Error("Company Name exists!"));
}
});
});
const cModel = mongoose.model("cmodel", schema)
This error doesn't have anything to do with lambda, except that the execution environment in lambda seems to be swallowing the error in the async method. To see the error being thrown, you can wrap the contents of your callback in a try {...} catch (e) {...} block and log the error in the catch block:
const schema = new mongoose.Schema({})
schema.pre('save', function (next) {
try {
cModel.find({name: this.name}, function (err, docs) {
try {
if (!docs.length){
next();
} else {
console.log('company name exists: ', this.name);
next(new Error("Company Name exists!"));
}
} catch (e) {
console.error('error in cModel.find: ' + e.message)
}
});
} catch (e) {
console.error('error in pre save : ' + e.message)
}
});
const cModel = mongoose.model("cmodel", schema)
Update
Using .pre('update'... will have this referencing the query, not the document, as the document is never loaded. You can access parts of the query using getFilter() and getUpdate().
Here is an example to check if company exists before making an update:
const schema = new mongoose.Schema({})
schema.pre('update', function (next) {
let newName = this.getUpdate().name;
cModel.find({name: newName }, function (err, docs) {
if (!docs.length){
next();
} else {
console.log('company name exists: ', newName);
next(new Error("Company Name exists!"));
}
});
});
const cModel = mongoose.model("cmodel", schema)

Related

how to get callback return value in nestjs

I am going to use vonage for text service.
However, only node.js syntax exists, and the corresponding API is being used.
There is a phenomenon that the callback is executed later when trying to receive the values ​​returned from the callback to check for an error.
How can I solve this part? The code is below.
await vonage.message.sendSms(from, to, text, async (err, responseData) => {
if (err) {
console.log('1');
result.message = err;
} else {
if (responseData.messages[0]['status'] === '0') {
console.log('2');
} else {
console.log('3');
result.error = `Message failed with error: ${responseData.messages[0]['error-text']}`;
}
}
});
console.log(result);
return result;
When an error occurs as a result of executing the above code,
result{error:undefined}
3
Outputs are in order.
From what I can understand the issue is that you are passing a async callback. you could simply just give vonage.message.sendSms() a synchronous callback like so.
const result = {};
vonage.message.sendSms(from, to, text, (err, responseData) => {
if (err) {
console.log('1');
result.message = err;
} else {
if (responseData.messages[0]['status'] === '0') {
console.log('2');
} else {
console.log('3');
result.error = `Message failed with error: ${responseData.messages[0]['error-text']}`;
}
}
});
if you want to use async or promises I would suggest something like this
const sendSMS = (from, to, text) => new Promise( (resolve, reject) => {
vonage.message.sendSms(from, to, text, (err, responseData) => {
if (err) {
reject(err);
} else {
resolve(responseData);
}
});
});
// elsewhere
sendSMS(from, to, text)
.then(...)
.catch(...);

ldapjs handling client.search response

I have the below code which is binding to an LDAP server and I want to return the user that I have added "ab" within the "interviewees" group (code taken from ldapjs client api page). I can see I am getting back a response from the server with the expected EventEmitter object. I am expecting to see information about the user when calling logging console.log() on the searchEntry object. I appear to have no searchEntry objects. Is my DN for my user correct? I am currently unsure whether the issue is with my query and I am not getting any data back or whether I am failing to process the response correctly?
const client = ldap.createClient({ url: 'ldap://' + LDAP_SERVER + ':' + LDAP_PORT });
// Connect and bind to the Active Directory.
const connectToClient = async () => {
const secret = LDAP_SECRET_KEY;
return await new Promise((resolve, reject) => {
client.bind(LDAP_USER, secret, function (err, res) {
if (err) {
console.error(err);
reject('Failed to connect to LDAP server');
} else {
resolve('Connected to LDAP server');
}
});
});
};
onst searchADForUser = async () => {
return await new Promise((resolve, reject) => {
client.search('CN=ab,OU=interviewees,OU=Users,OU=interview,DC=interview,DC=workspace,DC=com', function (err, res) {
if (err) {
console.error(err);
reject('Error searching LDAP server');
} else {
res.on('searchEntry', function (entry) {
console.log('entry: ' + JSON.stringify(entry.object));
});
res.on('searchReference', function (referral) {
console.log('referral: ' + referral.uris.join());
});
res.on('error', function (err) {
console.error('error: ' + err.message);
});
res.on('end', function (result) {
console.log('status: ' + result.status);
});
resolve(res);
}
});
});
};
const handler = async (event) => {
try {
return responses.success(
await connectToClient().then(async function(event) {
console.log(event);
await searchADForUser().then(function(event) {
console.log(event);
}).catch(function(event) {
console.log(event);
})
}).catch(function(event) {
console.log(event);
})
);
} catch (err) {
console.error(err);
return responses.error(err);
} finally {
client.unbind();
}
};
The active directory structure is below
The central issue I was having was understanding how to process the returned EventEmitter object from the search function. I need to add to an array on each searchEntry event and then return that entry in my resolve callback function only once the end event had occurred. The code above was calling resolve immediately and hence no searchEntry events or the end event had been processed yet.
Code I am now using below:
function (err, res) {
if (err) {
console.error(err);
reject(new Error('Error retrieving users from Active Directory'));
} else {
const entries = [];
res.on('searchEntry', function (entry) {
entries.push(entry);
});
res.on('searchReference', function (referral) {
console.log('referral: ' + referral.uris.join());
});
res.on('error', function (err) {
console.error('error: ' + err.message);
});
res.on('end', function (result) {
console.log('status: ' + result.status);
if (result.status !== 0) {
reject(new Error('Error code received from Active Directory'));
} else {
resolve(entries);
}
});
}
}

Store collection value to variable

I am having issues storing a value in mongodb to a variable to use within my webpage.
When the user fills out a form on my website, I am trying to figure out what the arrivalTrailer was when the user filled out the arrival form.
So far I have
function previousLoad(loadNumber, callback){
CheckCall.find({loadNumber: loadNumber}).sort({date: 'desc'}).limit(1), function(err, arrival){
if (err){
callback(err, null);
}
else {
callback(null, arrival[0]);
}
}};
previousLoad(loadNumber, function(err, arrival){
if (err){
console.log(err);
}
else{
arrivalTrailer = arrival;
console.log(arrival);
}
});
console.log(previousLoad.arrival);
console.log(arrivalTrailer);
Both output as undefined when I try to console.log the variables.
Thank you :D
Try this :
async function previousLoad(loadNumber) {
try {
let resp = await CheckCall.find({ loadNumber: loadNumber }).sort({ date: -1 }).limit(1)
return resp[0]
} catch (error) {
console.log('error ::', error)
throw new Error (error)
}
}
/** You can return response from previousLoad but to test it, Call it from here */
previousLoad(loadNumber).then(resp => { console.log('successfully found ::', resp)}).catch(err => { console.log('Error in DB Op ::', err)});

Error in function does not pass test

I'm learning about MongoDb and the exercise of the module is about a function in MongoDb to return the match in the database with the parameter "Director" that I pass but doesn't pass the test. This is my code:
In movies.js
exports.byDirector = function(db, director, callback) {
// TODO: implement
db.collection('movies').find(
{"director" : director}).sort({title : 1}).toArray(function(error, docs){
if (error){
console.log(error);
process.exit(1);
}
docs.forEach(function(doc){
console.log(JSON.stringify(doc));
});
process.exit(0);
})
callback(null, []);
};
This is the function's test:
it('returns multiple results ordered by title', function(done) {
dbInterface.byDirector(db, 'George Lucas', function(error, docs) {
assert.ifError(error);
assert.ok(Array.isArray(docs));
assert.equal(docs.length, 4);
assert.equal(docs[0].title, 'Attack of the Clones');
assert.equal(docs[1].title, 'Revenge of the Sith');
assert.equal(docs[2].title, 'Star Wars');
assert.equal(docs[3].title, 'The Phantom Menace');
docs.forEach(function(doc) {
delete doc._id;
});
assert.deepEqual(Object.keys(docs[0]), ['title', 'year', 'director']);
++succeeded;
georgeLucasMovies = docs;
done();
});
});
var succeeded = 3;
What's wrong?
Thank you so much for your help.
You are calling the callback function outside the toArray callback function
Try this
exports.byDirector = function(db, director, callback) {
// TODO: implement
db.collection('movies').find(
{"director" : director}).sort({title : 1}).toArray(function(error, docs){
if (error){
callback(err, null);
}
docs.forEach(function(doc){
console.log(JSON.stringify(doc));
});
callback(null, docs);
});
};

Using design documents in pouchDB with crypto-pouch

After testing pouchDB for my Ionic project, I tried to encrypt my data with crypto-pouch. But I have a problem with using design documents. I used the following code:
One of my design documents:
var allTypeOne = {
_id: '_design/all_TypeOne',
views: {
'alle_TypeOne': {
map: function (doc) {
if (doc.type === 'type_one') {
emit(doc._id);
}
}.toString()
}
}
};
For init my database:
function initDB() {
_db = new PouchDB('myDatabase', {adapter: 'websql'});
if (!_db.adapter) {
_db = new PouchDB('myDatabase');
}
return _db.crypto(password)
.then(function(){
return _db;
});
// add a design document
_db.put(allTypeOne).then(function (info) {
}).catch(function (err) {
}
}
To get all documents of type_one:
function getAllData {
if (!_data) {
return $q.when(_db.query('all_TypeOne', { include_docs: true}))
.then(function(docs) {
_data = docs.rows.map(function(row) {
return row.doc;
});
_db.changes({ live: true, since: 'now', include_docs: true})
.on('change', onDatabaseChange);
return _data;
});
} else {
return $q.when(_data);
}
}
This code works without using crypto-pouch well, but if I insert the _db.crypto(...) no data is shown in my list. Can anyone help me? Thanks in advance!
I'm guessing that your put is happening before the call to crypto has finished. Remember, javascript is asynchronous. So wait for the crypto call to finish before putting your design doc. And then use a callback to access your database after it's all finished. Something like the following:
function initDB(options) {
_db = new PouchDB('myDatabase', {adapter: 'websql'});
if (!_db.adapter) {
_db = new PouchDB('myDatabase');
}
_db.crypto(password)
.then(function(){
// add a design document
_db.put(allTypeOne).then(function (info) {
options.success(_db);
})
.catch(function (err) { console.error(err); options.error(err)})
.catch(function (err) { console.error(err); options.error(err);})
}
}
initDB({
success:function(db){
db.query....
}
)