Ldapjs wait until search is completed - javascript

I have the Problem that the return is made before methodStatus is set to true (so the return is always false even when I can see 'success' in the console log)
function anmelden(username, userPassword){
var methodStatus = false;
var opts = {
filter: 'sAMAccountName=' + username,
scope: 'sub'
};
ldapClient.search('OU=secret,OU=secret,DC=secret,DC=secret', opts, function(err, res) {
res.on('searchEntry', function(entry) {
var userClient = ldap.createClient({url: 'ldap://secret:1111'});
userClient.bind(entry.object.dn + '', userPassword, function(err) {
if(err) {
console.log('failed')
methodStatus = false;
} else {
console.log('success')
methodStatus = true;
}
ldapBind();
});
});
console.log('end');
return methodStatus;
});
}
This is the console log:
end
success
Thank you for your help :)

it is because of asynchrony. the return is invoked before the callback of the res.on is invoked. there are a lot of ways to handle it, for example to add a callback to the anmelden and to invoke it when the work is done:
function anmelden(username, userPassword, callback){
var methodStatus = false;
var opts = {
filter: 'sAMAccountName=' + username,
scope: 'sub'
};
ldapClient.search('OU=secret,OU=secret,DC=secret,DC=secret', opts, function(err, res) {
res.on('searchEntry', function(entry) {
var userClient = ldap.createClient({url: 'ldap://secret:1111'});
userClient.bind(entry.object.dn + '', userPassword, function(err) {
if(err) {
console.log('failed')
methodStatus = false;
} else {
console.log('success')
methodStatus = true;
}
ldapBind();
});
});
res.on('end', function () {
callback(methodStatus);
});
});
}
and to invoke it in the way like this:
anmelden('user', 'pass', function (methodStatus){
console.log('the status is %s', methodStatus);
})

Related

Elasticsearch.js - wait for ping to complete, async call

I am playing with elasticsearch.js from the browser. I would like to ping elasticsearch, wait for the request to complete and then return the result of the connection. But right now it is happening asynchronously, and returning undefined even when the connection is ok. I have code like this:
var connectionOK = false;
function createElasticsearchClient(hostAddress) {
var client = new $.es.Client({
hosts: hostAddress
});
return client;
}
function checkElasticsearchConnection(client) {
$.when(pingElasticsearch(client)).done(function () {
return connectionOK;
});
}
function pingElasticsearch(client) {
console.log("ELASTICSEARCH: Trying to ping es");
client.ping({
requestTimeout: 30000,
// undocumented params are appended to the query string
hello: "elasticsearch"
}, function (error) {
if (error) {
console.error('ELASTICSEARCH: Cluster is down!');
connectionOK = false;
console.log("INSIDE: " + connectionOK);
} else {
console.log('ELASTICSEARCH: OK');
connectionOK = true;
console.log("INSIDE: " + connectionOK);
}
});
}
and how it is used:
var esClient = createElasticsearchClient("exampleserver.com:9200");
var esCanConnect = (checkElasticsearchConnection(esClient));
You're mixing asynchronous functions with synchronous functions. You could go with this approach instead:
function createElasticsearchClient(hostAddress, callback) {
var client = new $.es.Client({
hosts: hostAddress
});
return callback(client);
}
function pingElasticsearch(client, callback) {
console.log("ELASTICSEARCH: Trying to ping es");
client.ping({
requestTimeout: 30000,
// undocumented params are appended to the query string
hello: "elasticsearch"
}, function (error) {
if (error) {
return callback('ELASTICSEARCH: Cluster is down!');
} else {
return callback(null);
}
});
}
And then run
createElasticsearchClient("exampleserver.com:9200", function(esClient) {
pingElasticsearch(esClient, function(err) {
if (err) console.log(err);
else {
//Everything is ok
console.log('All good');
}
});
});

nested Async not executing as expected

I am new to node js and I am trying to use async module to eliminate the setTimeouts. Here I am facing a problem. It is not working as expected. It calls the second function even before the first function completes execution. I searched for answers and tried multiple ways. But it doesn't seem to work. It prints "Inside db insert in async series" even before the async.forEach finishes. Can anyone please check the code and tell me where I'm going wrong?
setTimeout(function() {
async.series([function(callback1) {
console.log("Inside async series");
try {
var msg = "";
var datas = [];
for (var i = 0; i < service_name.length; i++) {
console.log("Inside for loop service names");
var child = {
"space_guid": space_guid,
"name": service_name[i],
"service_plan_guid": service_plan_guid[i]
};
datas.push(child);
console.log("datas array===" + JSON.stringify(datas))
}
async.forEach(datas, function(data1, callback) {
console.log("Inside async task");
var data = JSON.stringify(data1);
console.log("data value===" + JSON.stringify(data));
var options = {
host: 'api.ng.bluemix.net',
path: '/v2/service_instances' +
'?accepts_incomplete=true',
method: 'POST',
headers: {
'Authorization': full_token_new
}
};
console.log("options is" + JSON.stringify(options));
var reqst = http.request(options, function(res) {
console.log("Sent for request");
res.setEncoding('utf8');
res.on('data', function(chunk) {
msg += chunk;
});
res.on('end', function() {
try {
console.log("message =======", msg);
console.log("-----------------------------------------");
msg = JSON.stringify(msg);
msg1 = JSON.parse(msg);
console.log("printing msg--" + msg1);
console.log("-----------------------------------------");
console.log("here i am", i);
console.log(service_name.length - 1);
callback();
} catch (err) {
console.log(err);
}
});
});
reqst.on('error', function(e) {
console.log(e);
});
reqst.write(data);
reqst.end();
}, function(err) {
console.log("for each error" + err);
});
callback1(null, null);
} catch (err) {
console.log(err);
}
},
function(callback1) {
console.log("Inside db insert in async series")
db_insert(service_name, solnName, full_token_new, uname, version);
callback1(null, null);
}
],
function(err, results) {
if (err) {
console.log("There's an error" + err);
} else {
console.log("result of async", results);
}
})
}, 3000)
You are mixing try...catch with asynchronous code, this is bad practice and almost impossible to do right.
Also, your error stem from the fact you are calling callback just after async.forEach, which don't finish, and go to the next step.
Also, what do you mean by "eliminate the timeout"? Your whole code is in it, you can remove it whenever you want.
'use strict';
async.series([
(callback) => {
let msg = "",
datas = [],
i = 0;
while(i < service_name.length) {
let child = {
"space_guid": space_guid,
"name": service_name[i],
"service_plan_guid": service_plan_guid[i]
};
datas.push(child);
i = i + 1;
}
async.forEach(datas, (data1, callback) => {
let data = JSON.stringify(data1),
options = {
host: 'api.ng.bluemix.net',
path: '/v2/service_instances?accepts_incomplete=true',
method: 'POST',
headers: {
'Authorization': full_token_new
}
},
reqst = http.request(options, (res) => {
res.setEncoding('utf8');
res.on('data', (chunk) => {
msg += chunk;
});
res.on('end', () => {
msg = JSON.stringify(msg);
msg1 = JSON.parse(msg);
callback();
});
});
reqst.on('error', (error) => {
callback(error);
});
reqst.write(data);
reqst.end();
}, (error) => {
callback(error);
});
},
(callback) => {
db_insert(service_name, solnName, full_token_new, uname, version);
callback();
}
],
(error, results) => {
if (error) {
console.log("There's an error" + error);
} else {
console.log("result of async", results);
}
});
Since this smell heavily like a plssendzecode question, I've removed every console.log and gone ES6 to make sure you will not be able to use it as such and need to read the change I made.
I simplify code a little.
datas and processData aren't good names.
setTimeout(onTimer, 3000);
function onTimer() {
var datas = service_name.map(function(name, i) {
return {
space_guid: space_guid,
name: name,
service_plan_guid: service_plan_guid[i]
}
});
function processData(data, callback) {
var options = {
host: 'api.ng.bluemix.net',
path: '/v2/service_instances?accepts_incomplete=true',
method: 'POST',
headers: {
'Authorization': full_token_new
}
};
var reqst = http.request(options, function(res) {
var msg = '';
res.setEncoding('utf8');
res.on('data', function(chunk) {
msg += chunk;
});
res.on('end', function() {
try {
msg = JSON.parse(msg);
callback(null, msg);
} catch (err) {
callback(err);
}
});
});
reqst.on('error', callback);
reqst.write(JSON.stringify(data));
reqst.end();
}
async.map(datas, processData, function(err, results) {
if (err);
return console.log(err);
// process msg of each request db_insert(...);
});
};

Value of var goes back to empty after exiting function?

So I have an api request inside of a function thats placed in my Service script.. I have defined the variable "curruser" outside of the function so I can keep its value, however after exiting the follow Scirpt, curruser is empty??
services.js
function fbUserInfo() {
ngFB.api({
path: '/me',
params: {
fields: '/*params*/'
}
}).then(
function(user) {
curruser = user;
$http.get(/*send GET request to my server*/).success(function(response) {
if (response.length < 20) {
curruser.firsttime = true;
} else {
curruser.firsttime = false;
}
console.log(curruser);
console.log("1");
});
},
function(error) {
alert('Facebook error: ' + error.error_description);
});
}
So the console.log would return the proper JSON object I retrieved from facebook.. but when I return it in the return statement
return {
userInfo: function() {
fbUserInfo();
console.log(curruser);
return curruser;
}
it returns that curruser is an empty object! I did write
var curruser;
into the first line inside the ".factory"
you have to use then() since fbUserInfo() is async function
return {
userInfo: function() {
$.when(fbUserInfo())..then(
function(user) {
curruser = user;
$http.get(/*send GET request to my server*/).success(function(response) {
if (response.length < 20) {
curruser.firsttime = true;
} else {
curruser.firsttime = false;
}
console.log(curruser);
console.log("1");
});
},
function(error) {
alert('Facebook error: ' + error.error_description);
}).then(function(){
console.log(curruser);
return curruser;
})
}
Haven't tested this but might work.
var curruser;
function fbUserInfo( callback ) {
ngFB.api({
path: '/me',
params: {
fields: '/*params*/'
}
}).then(
function(user) {
curruser = user;
$http.get(/*send GET request to my server*/).success(function(response) {
if (response.length < 20) {
curruser.firsttime = true;
} else {
curruser.firsttime = false;
}
console.log(curruser);
console.log("1");
callback(curruser);
});
},
function(error) {
alert('Facebook error: ' + error.error_description);
});
}
return {
userInfo: function( callback ) {
fbUserInfo( function(data){
console.log(data);
callback(data);
});
}

How can convert this node.async code to using q? Do I need to return a promise?

In "view" method within my controller was previously using node-async but I wanted to try out using q.
I'm currently trying to convert this
exports.view = function (req, res) {
var category = req.params.category,
id = req.params.id,
ip = req.connection.remoteAddress,
slug = req.params.slug,
submission,
userId = typeof req.session.user !== 'undefined' && req.session.user.id ? req.session.user.id : null,
views;
var getSubmission = function (submissionId, callback) {
Submission.getSubmission({
id: submissionId
}, function (err, submission) {
if (err) {
callback(err);
} else if (submission) {
callback(null, submission);
} else {
callback(err);
}
});
};
async.waterfall([
function (callback) {
getSubmission(id, callback);
},
function (submission, callback) {
res.render('submission', {
title: submission.title + ' -',
submission: submission
});
}]);
To using q... I started doing something like:
var getSubmission = function(id) {
return Submission.getSubmission({
id : submissionId
}).then(function(submission) {
return submission;
});
};
q.fcall(getSubmission).then(function(submission) {
console.log(submission);
});
But it's not quite working as I intended. Am I doing something wrong here? How can I do this?
Is Submission.getSubmission a call to a database? Then you can't "chain" promises to that. You'll have to use the deferred method:
var getSubmission = function(id) {
var deferred = Q.defer();
Submission.getSubmission({
id: id
}, function(err, data){
if (err) {
deferred.reject(err);
} else {
deferred.resolve(data);
}
});
return deferred.promise;
}
getSubmission(some_id).then(successCallback, failureCallback);
You can also use Q#denodeify to convert a function using nodejs-style callbacks (function(err, data)) into a promise based function. Thus, the above can also be achieved by the following:
getSubmissionPromise = Q.denodeify(Submission.getSubmission);
getSubmissionPromise({id: some_id}).then(successCallback, failureCallback);

Node.js: Run the function on Event

function die(err) {
console.log('Uh oh: ' + err);
process.exit(1);
}
var box, cmds, next = 0, cb = function(err) {
if (err)
die(err);
else if (next < cmds.length)
cmds[next++].apply(this, Array.prototype.slice.call(arguments).slice(1));
};
cmds = [
function() { imap.connect(cb); },
function() { imap.openBox('INBOX', false, cb); },
function(result) { box = result; imap.search([ 'UNSEEN', ['SINCE', 'April 5, 2011'] ], cb); },
function(results) {
var msgCache = {},
fetch = imap.fetch(results, { request: { headers: ['from', 'to', 'subject', 'date'] } });
console.log('Now fetching headers!');
fetch.on('message', function(msg) {
msg.on('end', function() {
msgCache[msg.id] = { headers: msg.headers };
console.log(msg.headers.date[0]);
console.log(msg.headers.to[0]);
console.log(msg.headers.from[0]);
console.log(msg.headers.subject[0]);
var from = /(.*)?<(.*?)>/.exec(msg.headers.from[0]);
console.log(from[1]); // nome from
console.log(from[2]); // from
});
});
fetch.on('end', function() {
console.log('Done fetching headers!');
console.log('Now fetching bodies!');
fetch = imap.fetch(results, { request: { headers: false, body: '1' } });
fetch.on('message', function(msg) {
msg.data = '';
msg.on('data', function(chunk) {
msg.data += chunk;
});
msg.on('end', function() {
msgCache[msg.id].body = msg.data;
console.log(msg.data);
});
});
fetch.on('end', function() {
console.log('Done fetching bodies!');
cb(undefined, msgCache);
});
});
},
function(msgs) {
// Do something here with msgs, which contains the headers and
// body (parts) of all the messages you fetched
// console.log(msgs);
//imap.logout(cb);
imap.on('mail', function () {
// body...
console.log("New Email Has Arrived!");
next = 0;
cb();
})
}
];
cb();
When a new e-mail arrives imap.on('mail', function () I want it to run the cb() function again. However, it doesn't do anything after the console.log.
What am I doing wrong?
Thanks
reset your next counter, and your imap.on('mail', ... should be outside of cmds so that it's not bound again, and again, and again...
There are some modules around for "flattening" async operations to not end in callback hell.
e.g.: async
Maybe this could help you.

Categories

Resources