Promise in a function - javascript

I have been trying to add promise into a function, I have this error TypeError: sort_devices_name.then is not a function, function get_groups_devices is calling sort_devices_name and sort_devices_name is the function that i want to use as the promise.
});
// Find devices object id with relation of groups
get_groups_devices();
}
});
function sort_devices_name() {
return new Promise(
function (resolve, reject) {
var d_ids = data.map(function (d) {
return ObjectId(d.d_id);
});
devices_lookup.find({"_id": {$in: d_ids}}).sort({"device_name": 1}).toArray(function (err, d_data) {
if (err) {
return res.send(JSON.stringify(err));
}
else {
var modify_data = [];
d_data.forEach(function (val) {
data.forEach(function (val2) {
if (val2.d_id == val._id) {
modify_data.push({g_id: val2.g_id, d_id: val._id});
}
});
});
resolve(modify_data);
}
});
});
}
// Find devices object id with relation of groups (if any) from devices group relation table.
function get_groups_devices() {
devices_group.find({"g_id": {$in: groups_ids}}, {
"d_id": 1,
"g_id": 1,
"_id": 0
}).toArray(function (err, d_data) {
d_data = sort_devices_name(d_data);
sort_devices_name.then(function (d_data) {
console.log(d_data);
if (err) {
return res.send(JSON.stringify(err));
} else {

You need to call sort_devices_name, not just refer to it; add ():
sort_devices_name().then(function...
// --------------^^
The function doesn't have a then property, but the promise it returns does.

Related

how to get return value of promise

Here is a function to find mx records of a service and i need to save the one value(with the lowest priority) to make a request to it. How can I save and return this value?
const dns = require('dns');
const email = '...#gmail.com'
let res = email.split('#').pop();
function getMxRecords(domain) {
return new Promise(function(resolve, reject) {
dns.resolveMx(domain, function(err, addresses) {
if (err) {
//console.log(err, err.stack)
resolve(null);
} else {
//console.log(addresses);
let copy = [...addresses];
//console.log(copy);
let theone = copy.reduce((previous, current) => {
if (previous.priority < current.priority) {
return current;
}
return previous;
});
resolve(theone);
}
});
});
}
let a = getMxRecords(res);
console.log(a);
Yeah, so i need to export this module to make a request to it like below;
let socket = net.createConnection(25, request(email), () => {})
so for this my function should request me or array or object with only one value, when i'm trying it doesn't work, i always get this:
Promise { } //HERE IS RETURN FROM MY FUNCTION (WITH .THEN)
Error in socket connect ECONNREFUSED 127.0.0.1:25
A Promise is mostly an asynchronous call. It returns an Promise-Object that will resolve or reject the Promise. To access the result, you will call some functions:
function getMxRecords(domain) {
return new Promise(function(resolve, reject) {
dns.resolveMx(domain, function(err, addresses) {
if (err) {
//console.log(err, err.stack)
resolve(null);
} else {
//console.log(addresses);
let copy = [...addresses];
//console.log(copy);
let theone = copy.reduce((previous, current) => {
if (previous.priority < current.priority) {
return current;
}
return previous;
});
resolve(theone);
}
});
});
}
getMxRecords(res)
.then(yourResolveValueProvided => {
// Your code if the promise succeeded
})
.catch(error => {
// Your code if the promises reject() were called. error would be the provided parameter.
})

Callback function is not executed within returned Promise

I have two functions that return promise. The first one provide host value, and the second one use the host value to get IP address. I can see that the first function is running without any issue. But looks like the callback function side getHostIps is not executed at all. Not sure why it happens....what's wrong with my promise function?
my promise chain:
getHostedZoneId(dns)
.then(hostZoneId => {
getHostIps(dns, hostZoneId);
})
.then(hostIps => {
logger.Info(hostIps); //hostIps is undefined
})
.catch(err => logger.error(err));
getHostedZoneId:
var getHostedZoneId = function(dns) {
var params = {
DNSName: dns,
};
return new Promise((resolve, reject) => {
findHostZoneByDNS(params, function(err, data) {
if(err) {
reject(err);
}
else {
resolve(data);
}
});
});
}
getHostIps:
var getHostIps = function(dns, hostZoneId) {
var params = {
HostedZoneId: hostZoneId,
StartRecordName: dns,
};
return new Promise((resolve, reject) => {
findHostIps(params, function(err, data) {
//logger.info("get there");
if(err) {
reject(err);
}
else {
resolve(data);
}
});
});
}
I logged hostIps and err and data, all of them are defined. So I am sure that the callback function inside promise is not executed. But not sure how to fix it.
Any feedback is appreciated! Thanks!
You have to return the promise from your then statement to complete the chain.
getHostedZoneId(dns)
.then(hostZoneId => {
return getHostIps(dns, hostZoneId); // Add return
})
.then(hostIps => {
logger.Info(hostIps);
})
.catch(err => logger.error(err));

declaring a function to wait for a promise

I have the following function:
function JSON_to_buffer(json) {
let buff = Buffer.from(json);
if ( json.length < constants.min_draft_size_for_compression) {
return buff;
}
return zlib.deflate(buff, (err, buffer) => {
if (!err) {
return buffer;
} else {
return BPromise.reject(new VError({
name: 'BufferError',
}, err));
}
});
}
I want to be able to run this but have it wait if it goes to the unzip call. I'm currently calling this within a promise chain and it's going back to the chain without waiting for this and returns after the previous promise chain has completed.
You can put that logic into a Promise along with an async function
function JSON_to_buffer(json) {
return new Promise(function (resolve, reject) {
let buff = Buffer.from(json);
if (json.length < constants.min_draft_size_for_compression) {
return resolve(buff);
}
zlib.deflate(buff, (err, buffer) => {
if (!err) {
resolve(buffer);
} else {
reject(err);
/*return BPromise.reject(new VError({
name: 'BufferError',
}, ));*/
}
});
});
}
async function main() {
try {
let buffer = await JSON_to_buffer(myJSON);
} catch (e) {
console.log(e.message);
}
}

Calling a promise function recursively

I'm trying to call a promise function recursively.
The following call service.getSentenceFragment() returns upto 5 letters from a sentence i.e. 'hello' from 'helloworld. Providing a nextToken value as a parameter to the call returns the next 5 letters in the sequence. i.e. 'world'. The following code returns 'hellohelloworldworld' and does not log to the console.
var sentence = '';
getSentence().then(function (data)) {
console.log(sentence);
});
function getSentence(nextToken) {
return new Promise((resolve, reject) => {
getSentenceFragment(nextToken).then(function(data) {
sentence += data.fragment;
if (data.nextToken != null && data.nextToken != 'undefined') {
getSentence(data.NextToken);
} else {
resolve();
}
}).catch(function (reason) {
reject(reason);
});
});
}
function getSentenceFragment(nextToken) {
return new Promise((resolve, reject) => {
service.getSentenceFragment({ NextToken: nextToken }, function (error, data) {
if (data) {
if (data.length !== 0) {
resolve(data);
}
} else {
reject(error);
}
});
});
}
Cause when you do this:
getSentence(data.NextToken);
A new Promise chain is started, and thecurrent chain stays pending forever. So may do:
getSentence(data.NextToken).then(resolve, reject)
... but actually you could beautify the whole thing to:
async function getSentence(){
let sentence = "", token;
do {
const partial = await getSentenceFragment(token);
sentence += partial.fragment;
token = partial.NextToken;
} while(token)
return sentence;
}
And watch out for this trap in getSentenceFragment - if data is truthy but data.length is 0, your code reaches a dead end and the Promise will timeout
// from your original getSentenceFragment...
if (data) {
if (data.length !== 0) {
resolve(data);
}
/* implicit else: dead end */
// else { return undefined }
} else {
reject(error);
}
Instead, combine the two if statements using &&, now our Promise will always resolve or reject
// all fixed!
if (data && data.length > 0)
resolve(data);
else
reject(error);
You could recursively call a promise like so:
getSentence("what is your first token?")
.then(function (data) {
console.log(data);
});
function getSentence(nextToken) {
const recur = (nextToken,total) => //no return because there is no {} block so auto returns
getSentenceFragment(nextToken)
.then(
data => {
if (data.nextToken != null && data.nextToken != 'undefined') {
return recur(data.NextToken,total + data.fragment);
} else {
return total + data.fragment;
}
});//no catch, just let it go to the caller
return recur(nextToken,"");
}
function getSentenceFragment(nextToken) {
return new Promise((resolve, reject) => {
service.getSentenceFragment({ NextToken: nextToken }, function (error, data) {
if (data) {
if (data.length !== 0) {
resolve(data);
}
} else {
reject(error);
}
});
});
}

Promise inside promise

I am trying to write this code with Promise. but I don't know how to write promise inside Promise and loop.
I tried to think like this but insertBook function become asynchronously.
How can I get bookId synchronously?
update: function(items, quotationId) {
return new Promise(function(resolve, reject) {
knex.transaction(function (t) {
Promise.bind(result).then(function() {
return process1
}).then(function() {
return process2
}).then(function() {
var promises = items.map(function (item) {
var people = _.pick(item, 'familyName', 'firstNumber', 'tel');
if (item.type === 'book') {
var book = _.pick(item, 'name', 'bookNumber', 'author');
var bookId = insertBook(t, book);
var values = _.merge({}, people, {quotation: quotationId}, {book: bookId});
} else {
var values = _.merge({}, people, {quotation: quotationId});
}
return AModel.validateFor(values);
});
return Promise.all(promises);
}).then(function(items) {
var insertValues = items.map(function (item) {
return People.columnize(item);
});
return knex('people').transacting(t).insert(insertValues);
}).then(function() {
return process5
}).then(function() {
...........
}).then(function() {
t.commit(this);
}).catch(t.rollback);
}).then(function (res) {
resolve(res);
}).catch(function(err) {
reject(err);
});
});
}
function insertBook(t, book){
return Promise.bind(this).then(function () {
return Book.columnizeFor(book);
}).then(function (value) {
return knex('book').transacting(t).insert(value, "id");
});
}
You dont need to get bookid synchronously, you can handle it asynchronously correctly. Also, it is possible you want all book insertions happen sequentially, so I refactored the Promise.all part. (done that just to give you an idea. Promise.all should work fine if insertions in parallel are allowed). Furthermore, I think you shouldn't use Promise.bind. To be honest I dont even know what it does, one thing for sure: it doesn't work with standard promises. So here is an example how I think it should work:
update: function(items) {
return new Promise(function(resolve) {
knex.transaction(function (t) {
resolve(Promise.resolve().then(function() {
return process1;
}).then(function() {
return process2;
}).then(function() {
var q = Promise.resolve(), results = [];
items.forEach(function (item) {
q = q.then(function() {
var book = _.pick(item, 'name', 'bookNumber', 'author');
return insertBook(t, book);
}).then(function(bookId) {
var people = _.pick(item, 'familyName', 'firstNumber', 'tel');
var values = _.merge({}, people, {book: bookId});
return AModel.validateFor(values);
}).then(function(item) {
results.push(item);
});
});
return q.then(function() {
return results;
});
}).then(function(items) {
return process4
}).then(function() {
t.commit(result);
}).catch(function(e) {
t.rollback(e);
throw e;
}));
});
});
}
function insertBook(t, book){
return Promise.resolve().then(function () {
return Book.columnizeFor(book);
}).then(function (value) {
return knex('book').transacting(t).insert(value, "id");
});
}
Assuming that insertBook returns a promise you could do
var people = _.pick(item, 'familyName', 'firstNumber', 'tel');
if (item.type === 'book') {
var book = _.pick(item, 'name', 'bookNumber', 'author');
return insertBook(t, book)
.then(bookId => _.merge({}, people, {quotation: quotationId}, {book: bookId}))
.then(AModel.validateFor)
} else {
return Promise.resolve(_.merge({}, people, {quotation: quotationId}))
.then(AModel.validateFor)
}

Categories

Resources