How do I run a function after using array.map? - node.js

What I'm trying to do is run a function after using array.map. Theoretically, I should be able to just run the after the array.map. However, for some reason, it's running the function before array.map is finished. How do I fix this?
Here's my code.
var channelIds = channelNames.map(function (name) {
request(`https://www.googleapis.com/youtube/v3/channels?key=${key}&forUsername=${name}&part=id`, function (error, response, body) {
if (error) {
callback(error);
} else {
var data = JSON.parse(body);
if (data.items.length == 0) {
callback(`Error: No channel id found for ${name}`);
} else {
return data.items[0].id;
}
}
});
});
function test() {
console.log(channelIds);
}
test();
EDIT:
One way which was suggested was to use async.map. For some reason, it doesn't want to run the specified callback function like how the documentation says it should.
Here's how I'm doing it now.
async.map(channelNames, function (name) {
request(`https://www.googleapis.com/youtube/v3/channels?key=${key}&forUsername=${name}&part=id`, function (error, response, body) {
if (error) {
callback(error);
} else {
var data = JSON.parse(body);
if (data.items.length == 0) {
callback(`Error: No channel id found for ${name}`);
} else {
return data.items[0].id;
}
}
});
}, function (error, results) {
console.log(results);
});
Documentation: https://caolan.github.io/async/docs.html#map

How about using Promise.all to resolve all async functions before you call test method?
Try this :
const promiseArray = channelNames.map(function (name) {
return new Promise(function (resolve, reject) {
request(`https://www.googleapis.com/youtube/v3/channels?key=${key}&forUsername=${name}&part=id`, function (error, response, body) {
if (error) {
callback(error); return reject(error);
} else {
var data = JSON.parse(body);
if (data.items.length == 0) {
callback(`Error: No channel id found for ${name}`);
return reject(`Error: No channel id found for ${name}`);
} else {
return resolve(data.items[0].id);
}
}
});
});
});
Promise.all(promiseArray).then(function(channelIds) {
console.log(channelIds);
})

Related

nodejs: Not able to read response from callback function in the main function

Noob in nodejs here and still trying to learn how nodejs works. Could you please let me know how can I pass the callback response from "getDatafromCosmosDB" function into a variable in the main function and print those values.
When I try to assign getDatafromCosmosDB to a variable "respdata" and try to print it, it is not working.
async function main(params, callback) {
const logger = Core.Logger('main2', { level: params.LOG_LEVEL || 'info' })
try {
logger.info('main action')
const respdata = getDatafromCosmosDB(function(response){
console.debug(response)
return response
});
console.debug(respdata)
} catch (e) {
console.debug(e)
}
}
exports.main = main
async function getDatafromCosmosDB(callback){
var query = new azure.TableQuery()
.top(5)
tableService.queryEntities('myCosmosTable', query, null, function (error, result, response) {
if (!error) {
console.log('success')
return callback(result.entries)
}
});
}
Try something like this,
import {
createTableService,
services,
ServiceResponse,
TableQuery
} from 'azure-storage';
getDatafromCosmosDB(): Promise<ServiceResponse> {
return new Promise(async (resolve, reject) => {
this.tableService.queryEntities(
this.tableName,
query,
null,
(error, _, response) => {
if (!error) {
resolve(response);
} else {
reject(error);
}
}
);
});
}
and invoke like,
this.getDatafromCosmosDB().then(data => {
console.log(data);
}

how to return results to postman using nodejs.i couldn't send result

App.js
app.get('/getCus', function (req, res) {
var id= req.query;
cus_controller.getCus(id,function(response) {
res.json(response);
});
});
cus_controller.js:
module.exports ={
getCus: function (id, callback) {
getCus = function () {
getOneCus(id).then(result => {
callback(result);
}).catch(err => {
callback(err)
})
}
process.nextTick(getCus);
},
}
async function getOneCus(id) {
auth.authClient(function (err, client) {
if (client) {
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
}
getCus(id,client, callback);
}
else {
console.error(err);
}
})
}
var getCus = (id, client, callback) => {
client
.invokeApi(null, `/cus/${id}`, 'GET')
.then(function (result) {
console.log(result.data);
return result.data
})
.catch(function (result) {
if (result.response) {
console.dir({
status: result.response.status,
statusText: result.response.statusText,
data: result.response.data
});
} else {
console.log(result.message);
}
});
}
in getCus method getting a response in the console. however, couldn't get a response in postman.it shows 200 status code but didn't get a response. Someone help me, please. I could not find any solution for this.i tried many methods like return data and res.send(data).
You're passing a callback function to getCus, but you never use it. It looks like you meant call it instead of return the result:
client
.invokeApi(null, `/cus/${id}`, 'GET')
.then(function (result) {
console.log(result.data);
callback(result.data); // <-- here
})
Alternatively, if you return the result as you currently do, then you wouldn't pass a callback to getCus but would instead use a .then() structure:
cus_controller.getCus(id).then(function(response) {
res.json(response);
});
But be sure to also return the top-level Promise by returning the call to client.invokeApi:
return client // <-- here
.invokeApi(null, `/cus/${id}`, 'GET')
.then(function (result) {
console.log(result.data);
return result.data
})

Update from bd with success but returns undefined on Controller Node.Js

Hy everyone, I'm having some troubles with my rest api. I have in my ui a button where I click to update the state of a bus ( visible / not visible). By clicking on the button I can update the state of the item on the map.
So my problem is when I update the info in my DB in my controller i get the result of this as undefined but the resolve of the db returns
{"command":"UPDATE","rowCount":1,"oid":null,"rows":[],"fields":[],"_parsers":[],"RowCtor":null,"rowAsArray":false}
My return.rows[0] becomes undefined on resolve (I console.log this value and i dont understand why this is happening).
ServicesController.js
ServicesController.prototype.updateMap = function (req, res, next) {
var data = req.body;
if (isEmptyObject(data)) {
res.status(400).send({error: errorMessage.emptyBody});
return;
}
if (data.sn === undefined || data.sn === "") {
res.status(400).send({error: "Invalid serial number"});
return;
}
Database.Services.getDeviceBySn(data.sn).then(function (device) {
var map_data={
"isRoot": data.root,
"visible": data.visible
}
Database.Services.addMapInfo(map_data, device.id).then(function (map) {
console.log("updateMap depois do addMapInfo --- map >>> ", map);
if (map) {
res.status(200).send(map);
} else {
res.status(404).end();
}
}).catch(function (e) {
res.status(500).send(e);
});
}).catch(function (e) {
res.status(500).send(e);
});
}
ServicesDatabase.js
ServicesDatabase.prototype.addMapInfo = function (data, deviceId) {
return new Promise(function (resolve, reject) {
pg.connect(dbStatsConnectionString, function (err, client, done) {
if (err) {
reject(err);
return
}
client.query("UPDATE device_services SET data=jsonb_set(data::jsonb,'{map}',$1::jsonb,true), modified_date=NOW() WHERE device_id=$2", [data, deviceId], function (err, result) {
done();
if (err) {
reject(err);
} else {
resolve(result.rows[0]);
}
});
});
});
}
My parameters are data {"isRoot":"false","visible":"online"} and deviceId "1f110136-9490-4ea5-a46d-3fdfa65ea0ab"
My controller always return 404 because of this
if (map) {
res.status(200).send(map);
} else {
res.status(404).end();
}
Anyone can help me? I dont get it...

I need help about Asynchronus call in node.js with Mongodb, i need to call synchronous method for further processing of data

calling id from mongodb with callback function
var GetID = function (nameval, callback) {
console.log(nameval);
console.log("munesh hello");
GenerateID.find({ "id_name": nameval }, {
"id_code": 1,
"id_value": 1, "_id": 0
}, function (err, genvalue) {
if (err) {
console.log('hello');
}
else {
if (genvalue === null) {
callback(err, false);
}
else {
callback(err, true);
}
}
console.log(genvalue);
});
};
and calling above method so we need
so we need id from GenerateID.GetID and do our own work.
var region_id = GenerateID.GetID(name, function (error, result) {
if (error) {
console.log("getting any error");
} else {
console.log(region_id);
if (!result) {
console.log('data is not coming');
} else {
console.log('data is coming');
}
}
});
You have a number of issues. In the first piece of code, you need to pass the actual value when calling the callback.
In the second, you need to set region_id = result.
Ideally you would do this using promises as demonstrated below.
var GetID = function(nameval){
return new Promise((resolve,reject) => {
console.log(nameval);
console.log("munesh hello");
GenerateId.find({ "id_name" : nameval },{"id_code":1 , "id_value":1, "_id":0},
function( err , genvalue ) {
console.log(genvalue);
if (err) {
console.log('hello');
return reject()
}
if (genvalue == null) { return resolve(false); }
return resolve(genValue);
});
});
}
var GetIDPromise = GenerateId.GetID(name);
GetIDPromise.then(
genValue => {
if ( genValue == false ){
console.log('data is not coming');
// handle region id not being available. Perhaps return and show an error
}else{
var region_id = genValue;
// continue execution and use region id.
}
},
error => {
console.log("getting any error");
}
)

Converting async code to q/promise code in nodejs

I've read through a lot of different articles on promisejs but can't seem to get it to work for my code. I have async code that works and does what I need but it's very long and doesn't look as clean as it could with promise.
Here's the two links I've been really looking into: http://jabberwocky.eu/2013/02/15/promises-in-javascript-with-q/ and https://spring.io/understanding/javascript-promises.
mainCode.js
accountModel.findOne({username: body.username}, function(err, usernameFound) {
console.log("here");
if (err) {
console.log(err);
} else {
console.log("here1");
anotherClass.duplicateUsername(usernameFound, function(err, noerr) {
if (err) {
console.log("error");
res.status(409).send("username");
} else {
console.log("here2");
accountModel.findOne({email: body.email}, function(err, emailFound) {
if (err) {
console.log("error2");
} else {
console.log("here3");
console.log(emailFound);
}
});
}
});
}
});
// anotherclass.duplicateUsername
anotherClass.prototype.duplicateUsername = function(usernameFound, callback) {
if (usernameFound) {
callback(usernameFound);
} else {
callback();
}
}
current promise code (in mainCode.js):
var promise = userModel.findOne({
username: body.username
}).exec();
promise.then(function(usernameFound) {
console.log("usernameFound")
return userCheck.duplicateUsername(usernameFound);
}).then(function(usernameFound) {
console.log("NOERR:" + usernameFound + ":NOERR");
console.log("noerror");
return;
}, function(error) {
console.log(err);
console.log("error");
res.sendStatus(409);
return;
});
When I run my promise code, it goes to duplicateUsername, does callback() but then doesn't print anything in the promise code.
duplicationUsername needs to return a promise, otherwise the promise chaining will get the value returned from calling callback (which would be undefined).
Something like this should work:
anotherClass.prototype.duplicateUsername = function(usernameFound) {
var deferred = Q.defer();
if (usernameFound) {
deferred.resolve(usernameFound);
} else {
deferred.reject();
}
return deferred.promise;
}
So it seems like I needed to "promisify" my own functions before I could use them.
Here's how I did it with Q:
var Q = require('q');
anotherClass.prototype.duplicateUsername = function(username, callback) {
return new Promise(function(resolve, reject) {
var deferred = Q.defer();
if (usernameFound) {
deferred.reject("error);
} else {
deferred.resolve("no err: duplicate username");
}
deferred.promise.nodeify(callback);
return deferred.promise;
});
}
Here's how to do it with Bluebird:
userCheck.prototype.duplicateUsername = function(usernameFound) {
return new Promise(function(resolve, reject) {
if (usernameFound) {
reject("error");
} else {
resolve();
}
});
}
Then in my mainClass, I just used them by calling the methods and then .then(//blah)

Resources