I am calling from an angular app, using angularfire2, this.afDb.database is the db instance
const downloadsRef = this.afDb.database.ref('research_reports-published/' + rrid + '/' + field);
downloadsRef.transaction(function(fieldval) {
if (fieldval) {
fieldval = fieldval + 1;
}
return fieldval;
},
function(error, committed, snapshot) {
if (error) {
console.log('Transaction failed abnormally!', error);
} else if (!committed) {
console.log('We aborted the transaction (because ada already exists).');
} else {
console.log('User ada added!');
}
console.log('Adas data: ', snapshot.val());
}).then(function() {
console.log('Transaction successfully committed!');
}).catch(function(error) {
console.log('Transaction failed: ', error);
});
The code just silently prints
Adas data: oldvalue
Transaction successfully committed
and exits
Found the issue in above code. It should be
if (fieldval != null) {
fieldval = fieldval + 1;
}
as fieldval=0 also makes it false
Related
I have tried to use the following code to retrieve the Lotus user detail by Node.js.
let ActiveDirectory = require('activedirectory');
let config = {
attributes:{user: ["*"]},
url: 'ldap://mylotusdominoserver',
baseDN: 'OU=myOU,O=myOrg',
}
let ad = new ActiveDirectory(config);
ad.authenticate(user, password, function (err, auth) {
if (err) {
console.log('ERROR0: ' + JSON.stringify(err));
return;
}
if (auth) {
console.log('Authenticated!');
let query = "&(objectClass=*)(CN=Amy*)";
ad.find(query, (err, results) => {
if ((err) || (!results)) {
console.log('ERROR1: ' + err);
return;
}
console.log(results.other[0]);
});
}
else {
console.log('Authentication failed!');
}
});
It returns:
Authenticated!
{
dn: 'CN=Amy Tomson,OU=myOU,O=myOrg',
mail: 'amyt#myOU.myOrg',
sn: 'Amy',
cn: 'Amy Tomson'
objectclass: [Array],
givenname: 'Amy',
uid: 'amyt#myOU.myOrg',
maildomain: 'myOrg'
}
However, the return attributes do not include the working title of the user,
I have added the following attributes to force the server to return all attributes of the user.
attributes:{user: ["*"]},
However, it does not work.
My Lotus Note Domino Server version is 9.0.
Is it possible to fix it?
Finally, I use ldapjs library to fix the problem.
Here is the sample code:
const ldap = require('ldapjs');
var client = ldap.createClient({
url: 'ldap://mylotusdominoserver'
});
client.bind(userName, password, function(err) {
if (err) {
console.log('ERROR0: ' + JSON.stringify(err));
return;
}
});
let opts = {
attributes: ['givenname', 'sn', 'uid'],
filter: '&(title=Manager)(uid=*myOU.myOrg)',
scope: "sub",
}
client.search('OU=myOU,O=myOrg', opts, function(err, search) {
if (err) {
console.log('ERROR1: ' + JSON.stringify(err));
return;
}
let results = [];
search.on('searchEntry', function(entry) {
results.push(entry.object);
});
search.on('end', function(entry) {
console.log("End:" + entry.status);
console.log(results);
client.unbind(function(err) {
console.log("Unbinded.");
if (err) {
console.log('ERROR3: ' + JSON.stringify(err));
return;
}
});
});
search.on('error', error => {
if (error) {
console.log('ERROR2: ' + JSON.stringify(error));
return;
}
});
});
why am I returning a Uncaught TypeError: creacteAccount(...).then(...).catch is not a function? Is .catch() is unacceptable? Please bear with me since I am new with these technologies :)
function creacteAccount(db_name, contact, email) {
if (!(db_name > "" && contact > "" && email > "")) {
return Promise.reject("One of the parameters is empty");
}
return session.rpc('/custom/createdb', {db_name: db_name})
.then(function () {
console.log("Database created successfully");
return session.rpc('/custom/initdb', {db_name: db_name});
}).then(function () {
console.log("Database initialized successfully");
return session.rpc('/custom/installapps', {db_name: db_name});
}).then(function () {
console.log("Apps installed successfully");
return session.rpc('/custom/createaccount', {
db_name : db_name,
contact_name: contact,
email_from: email
});
}).then(function () {
console.log("User account created successfully");
});
}
creacteAccount(db_name, contact, email).then(function () {
console.log("Successfully creating your account")
}).catch(function (err) {
alert("Could not create account! (" + err + ")");
});
This is the logs: https://jpst.it/2p-nG
I did use sfDoc !== undefined, but still I'm getting the error of object is possibly undefined. Am I doing anything wrong here?
return database.runTransaction(function (transaction) {
return transaction.get(sfDocRef).then(sfDoc => {
if (!sfDoc.exists) {
throw "Document does not exist!";
}
if (sfDoc !== undefined) {
var usedCount = sfDoc.data().usedCount + 1;
transaction.update(sfDocRef, { usedCount: usedCount });
}
return transaction;
});
}).then(function () {
console.log("Tag field changed!");
return true;
}).catch(function (error) {
console.log("Error in changing Tag field: ", error);
return false;
});
Try this example. Check for the sfDoc and return transaction.update, So that then wait to resolve the promise. According to document, you don not has to check for sfDoc. It will be always defined.
return database
.runTransaction(function (transaction) {
return transaction.get(sfDocRef).then((sfDoc) => {
if (sfDoc && sfDoc.exists) {
var usedCount = sfDoc.data().usedCount + 1;
return transaction.update(sfDocRef, { usedCount: usedCount });
} else {
throw "Document does not exist!";
}
});
})
.then(function () {
console.log("Tag field changed!");
return true;
})
.catch(function (error) {
console.log("Error in changing Tag field: ", error);
return false;
});
Hello I am having issues deleting a document from MongoDb using an object
here is what I mean
const deleteTrimByName = function (db, callback) {
// Get the documents collection
const collection = db.collection(documentName)
// Insert some documents
console.log(trimNameToDelete)
collection.deleteOne({Video_trim: trimNameToDelete}, function (err, result) {
assert.equal(err, null)
assert.equal(1, result.result.n)
console.log('Removed the document')
callback(result)
})
fs.unlink('./public/videos/cut-videos/' + documentName + '/' + trimNameToDelete.trimName + '.mp4', (err) => {
if (err) {
console.log('failed to delete local image:' + err)
} else {
console.log('successfully deleted local image')
}
})
}
where trimNameToDelete evaluates to
{"trimName":"cut2","startTime":"00:00:05","endTime":"00:00:15"}
and the mongo document appears as this in the shell
{ "_id" : ObjectId("5abe67897a9b9e0933c64acd"), "Video_trim" : { "trimName" : "cut2", "startTime" : "00:00:05", "endTime" : "00:00:15" } }
the error I get is
AssertionError [ERR_ASSERTION]: 1 == 0
For technical reasons use the Id cannot be used for deleting.
Ah I found the issue, I needed to parse the trimNametoDelete, stupid mistake, I was sending the trimNametoDelete as a string.
const deleteTrimByName = function (db, callback) {
// Get the documents collection
const collection = db.collection(documentName)
console.log('>>>>>' + trimNameToDelete)
collection.deleteOne({Video_trim: JSON.parse(trimNameToDelete)}, function (err, result) {
assert.equal(err, null)
assert.equal(1, result.result.n)
console.log('Removed the document')
callback(result)
})
fs.unlink('./public/videos/cut-videos/' + documentName + '/' + JSON.parse(trimNameToDelete).trimName + '.mp4', (err) => {
if (err) {
console.log('failed to delete local image:' + err)
} else {
console.log('successfully deleted local image')
}
})
}
I have a NodeJS script that I have been working on, but the biggest problem I have is that chaining all of these promises is not only ugly to look at, but difficult to maintain as time goes on.
I want to convert these individual promises into one, using the Promise.all() method, but am not sure how I can get the same functionality and assign variables from one promise to another using this method.
For example, my second promise: methods.login() returns a sessionId that is used in almost every other promise. How would I assign that variable and pass it to further dependent promises using Promise.all()??
Here is my current code:
var zabbixApi = require('./zabbixapi.js');
var methods = require('./methods.js');
var fs = require('fs');
var SESSIONID;
function main() {
var apiVersion, loggedOut, numTemplates, numHosts, numHostGroups, numItems;
var templates = []
, hostGroups = []
, hosts = [];
/*var promises = [];
promises.push(zabbixApi(methods.getApiVersion()));
promises.push(zabbixApi(methods.login(SESSIONID)));
promises.push(zabbixApi(methods.getHostGroups(SESSIONID)));
promises.push(zabbixApi(methods.getTemplates(SESSIONID)));
promises.push(zabbixApi(methods.getHosts(SESSIONID)));
// promises.push(zabbixApi(methods.configExport(hostIds, templateIds, groupIds, SESSIONID)));
promises.push(zabbixApi(methods.logout(SESSIONID)));
Promise.all(promises).then(function (values) {
console.log('All promises completed.');
}, function (reason) {
console.log('Error completing promises: ' + reason);
});*/
// Get API version
zabbixApi(methods.getApiVersion())
// If successful, login to the API
.then(function (version) {
apiVersion = version.result;
// Verify that the API version returned is correct
if (apiVersion.length < 5 || !apiVersion) {
console.log('Error occurred retrieving API version: ' + version.error.data);
return 1;
} else {
return zabbixApi(methods.login(SESSIONID));
}
}, function (error) {
console.log('Error occurred retrieving API version: ' + error);
return 1;
// If login successful, continue operations until logged out or error
}).then(function (auth) {
SESSIONID = auth.result;
if (!SESSIONID) {
console.log('Error retrieving session id: ' + auth.error.data);
return 1;
} else {
console.log('Logged in successfully!');
return zabbixApi(methods.getHostGroups(SESSIONID));
}
}, function (error) {
console.log('Error occurred authenticating: ' + error);
return 1;
// Attempt to retrieve all hostgroup information
}).then(function (hostgroups) {
numHostGroups = hostgroups.result.length;
hostGroups = hostgroups.result;
if (!numHostGroups) {
console.log('Error occurred retrieving host groups: ' + hostgroups.error.data);
return 1;
} else {
return zabbixApi(methods.getTemplates(SESSIONID));
}
}, function (error) {
console.log('Error occurred retrieving host groups: ' + error);
return 1;
// Attempt to retrieve host information
}).then(function (template) {
numTemplates = template.result.length;
templates = template.result;
if (!numTemplates) {
console.log('Error occurred retrieving templates: ' + template.error.data);
return 1;
} else {
return zabbixApi(methods.getHosts(SESSIONID));
}
}, function (error) {
console.log('Error occurred retrieving templates: ' + error);
return 1;
// Attempt to retrieve host information
}).then(function (hosts) {
numHosts = hosts.result.length;
hosts = hosts.result;
if (!numHosts) {
console.log('Error occurred retrieving host groups: ' + hosts.error.data);
return 1;
} else {
var groupIds = []
, hostIds = []
, templateIds = [];
// Extract all groupIds for host groups
for (var i = 0; i < numHostGroups; i++) {
groupIds[i] = hostGroups[i].groupid;
}
// Extract all hostIds for hosts
for (var i = 0; i < numHosts; i++) {
hostIds[i] = hosts[i].hostid;
}
// Extract all templateIds for templates
for (var i = 0; i < numTemplates; i++) {
templateIds[i] = templates[i].templateid;
}
return zabbixApi(methods.configExport(hostIds, templateIds, groupIds, SESSIONID));
}
}, function (error) {
console.log('Error occurred retrieving host groups: ' + error);
return 1;
// Attempt to retrieve configuration information
}).then(function (config) {
//console.log(config);
if (config.error) {
console.log('Error occurred retrieving configuration: ' + config.error.message + ': ' + config.error.data);
return 1;
} else {
if (!writeToFile(config)) {
return 1;
} else {
console.log('Configuration details exported successfully.');
}
return zabbixApi(methods.logout(SESSIONID));
}
}, function (error) {
console.log('Error occurred retrieving configuration: ' + error);
return 1;
// Attempt to logout of API, if logout successful exit safely
}).then(function (logout) {
loggedOut = logout.result;
if (!loggedOut) {
console.log('Error logging out: ' + logout.error.data);
return 1;
} else {
console.log('Logged out successfully!');
return 0;
}
}, function (error) {
console.log('Error occurred logging out: ' + error);
return 1;
});
}
function writeToFile (config) {
fs.writeFile('zabbix_config_export.json', JSON.stringify(config), function (err) {
if (err) {
return console.log('Error writing configuration to file: ' + err);
}
});
return true;
}
main();
You can use Promise.all() on operations that can run in parallel, but not on operations that must be performed in a specific sequence.
In looking at your code, it appears that you do have a couple places where you can do some operations in parallel, but not all your operations can be done that way. It appears you can do things in this general sequence:
getApiVersion
Login to session
In parallel (getHostGroups, getTemplates, getHosts)
configExport previous results
In parallel (logout, writeToFile)
That can be achieved like this:
var zabbixApi = require('./zabbixapi.js');
var methods = require('./methods.js');
var fs = require('fs');
var SESSIONID;
function logout() {
if (SESSIONID) {
var p = zabbixApi(methods.logout(SESSIONID));
// clear SESSIONID to show that we've already launched a logout attempt, no need to try again
SESSIONID = null;
return p;
} else {
return Promise.resolve();
}
}
function main() {
var apiVersion, hostGroups, templates, hosts;
// Get API version
zabbixApi(methods.getApiVersion())
// If successful, login to the API
.then(function (version) {
apiVersion = version.result;
// Verify that the API version returned is correct
if (!apiVersion || apiVersion.length < 5) {
throw new Error('Error occurred retrieving API version: ' + version.error.data);
} else {
return zabbixApi(methods.login(SESSIONID));
}
}, function (error) {
throw new Error('Error occurred retrieving API version: ' + error);
// If login successful, continue operations until logged out or error
}).then(function (auth) {
SESSIONID = auth.result;
if (!SESSIONID) {
throw new Error('Error retrieving session id: ' + auth.error.data);
} else {
console.log('Logged in successfully!');
// now that we are logged in, a number of operations can be launched in parallel
return Promise.all([
zabbixApi(methods.getHostGroups(SESSIONID),
zabbixApi(methods.getTemplates(SESSIONID),
zabbixApi(methods.getHosts(SESSIONID)
]);
}
}, function (error) {
throw new Error('Error occurred authenticating: ' + error);
// we have hostGroups, templates and hosts here
}).then(function(r) {
// r[0] = hostGroups, r[1] = templates, r[2] = hosts
// check hostGroups
hostGroups = r[0].result;
if (!hostGroups.length) {
throw new Error('Error occurred retrieving host groups: ' + hostgroups.error.data);
}
// check templates
templates = r[1].result;
if (!templates.length) {
throw new Error('Error occurred retrieving templates: ' + template.error.data);
}
// check host information
hosts = r[2].result;
if (!hosts.length) {
throw new Error('Error occurred retrieving host groups: ' + hosts.error.data);
}
// utility function for retrieving a specific property from each array of objects
function getIds(array, prop) {
return array.map(function(item) {
return item[prop];
});
}
var groupIds = getIds(hostGroups, "groupid");
var hostIds = getIds(hosts, "hostid");
var templateIds = getIds(templates, "templateid");
return zabbixApi(methods.configExport(hostIds, templateIds, groupIds, SESSIONID));
}).then(function(config) {
if (config.error) {
throw new Error('Error occurred retrieving configuration: ' + config.error.message + ': ' + config.error.data);
}
// simultaneously write to file and logout (since these are not dependent upon one another)
return Promise.all(logout(), writeToFile(config));
}).then(function() {
// success here, everything done
}, function(err) {
// upon error, try to logout and rethrow earlier error
return logout().then(function() {
throw err;
}, function() {
throw err;
});
}).then(null, function(err) {
// error here
console.log(err);
});
}
function writeToFile (config) {
return new Promise(function(resolve, reject) {
fs.writeFile('zabbix_config_export.json', JSON.stringify(config), function (err) {
if (err) {
return Promise.reject(new Error('Error writing configuration to file: ' + err));
}
resolve();
});
});
}
main();
This also makes some other important structural changes/fixes:
Any time you have a reject/catch handler, if you don't either return a rejected promise or throw from that handler, then the promise chain will continue which is not what you want and you were doing that in almost every reject handler you had.
No need to have a reject handler for every single promise. If you just intend for any reject to stop the chain anyway, then you can just make sure that the reject reason is descriptive and do all failure logging one place at the end of the chain.
This uses Promise.all() in two places where operations can run in parallel because they are not dependent upon one another, but the code logic wants to know when they are all done.
writeToFile() is changed to return a promise.
Create a logout() function that can be safely called in several error paths so all error and success paths at least attempt the logout (if login succeeded)
Swap the two conditions when checking apiVersion because you should check !apiVersion first.
Promises.all is intended to handle asynchronous functions when they run in parallel and you need to wait until they all are finished. The promises in the code you shared are not independent so you can't use Promises.all here. Check out this reference to see the Promises.all usage.