looping through an array of objects using node js and mongodb - node.js

i am new with using mongodb and node am trying to loop through an array of objects from my database and display only the objects using a res.json, in my console.log it displays all the object, but in my postman using res.json it displays only one object please help
MY CODE
const course = res.GetUserDT.coursesHandled;
for (let index = 0; index < course.length; index++) {
console.log(course[index]);
}
const course = res.GetUserDT.coursesHandled;
for (let index = 0; index < course.length; index++) {
res.json(course[index]);
}
my console output
{ courseCode: '2103' }
{ courseCode: '2012' }
{ courseCode: '2062' }
my postman output
{ courseCode: '2103' }

Hi and welcome to Stackoverflow.
The Problem here is that res.json() sends a an immidiate response to the requestor - meaning a response is sent already within the first iteration of your for-loop.
I am also wondering why you need that loop - as you are not doing anything within it. So why don't you just send the array immidiately like so:
res.json(res.GetUserDT.coursesHandled);

You can only send res.json once.
To send all of them together you can create an array, push all the objects in the array and send it back as a response.
let arrayToReturn = []
for (let index = 0; index < course.length; index++) {
arrayToReturn.push(course[index])
}
res.json(arrayToReturn);
Update
#David's answer is the most accurate solution i.e just directly send the array as a response instead of looping
res.json(res.GetUserDT.coursesHandled);

Assuming that is express, res.json() will send the data and end the response.
try something like:
const responseArray = [];
for (let index = 0; index < course.length; index++) {
responseArray.push( course[index] );
}
res.json(responseArray);

Related

Test random URLs from spreadsheet using alasql

I have a large number of URLs within a xlsx file. What I'd like to do is randomly select some of these URLs, load them, then check that they return a status code of 200.
So I'm using the npm alasql package to do this.
At the moment, the following code successfully loads the first 5 URLs in the spreadsheet, checks that they 200, then finishes the test.
var alasql = require('alasql');
var axios = require('axios');
module.exports = {
'#tags': ['smokeTest'],
'Site map XML pages load': async (browser) => {
const result = await alasql.promise('select URL from xlsx("./testUrls.xlsx",{sheetid:"RandomUrls"})');
var xcelData = result.map(item => {
return item.URL;
});
async function siteMapUrlsTestArr(item) {
var response = await axios.get(browser.launch_url + item);
browser.verify.equal(response.status, 200);
console.log('Sitemap test URL =', (browser.launch_url + item));
}
for (let index = 0; index < xcelData.length; index++) {
if (index < 5) {
const xmlTestUrl = xcelData[index];
await siteMapUrlsTestArr(xmlTestUrl);
} else {}
}
},
'Closing the browser': function (browser) {
browser.browserEnd();
},
};
However, what I'd like to do is randomly select 5 URLs from the (large) list of URLs in the spreadsheet, rather than the first 5 URLs.
I appreciate that this will (probably) include using the Math.floor(Math.random() command, but I can't seem to get it to work no matter where I place this command.
Any help would be greatly appreciated. Thanks.
Your logic is flawed. Here's how.
You want to select 5 random URLs from a list and then, perform the operation on the items but what you're doing is you're getting all the items and running the operation using a loop on first five.
To correct it:
//Fixed to five as you only want to test 5 URLs.
for (let index = 0; index < 5; index++) {
//Selecting a Random item from the list using Math.random();
const xmlTestUrl = xcelData[Math.floor(Math.random() * xcelData.length)];
//Performing the HTTP response operation on it.
await siteMapUrlsTestArr(xmlTestUrl);
}
The aforementioned solution will select a random item in each loop and perform the HTTP response operation on it. The items will be randomly selected using Math.random().

Nodejs Webdav read multiple files (Problem with Array)

I am starting using NodeJs and webdav, I am using websockets to receive a list with the names of the images that I need to send to my app and then I have a for loop to send them to my app, but for some reason some of the images are undefined.
I am starting using NodeJs and webdav so I have no idea what's wrong.
for(let i = 0; i < ImagemList.length; i++){
wfs.readFile(ImagemList[i], "binary", function(err, data) {
Imagens[i] = data;
if(Imagens.length == ImagemList.length){
socket.emit("ImagemPost", Imagens);
}
});
}
For some reason I can't acess the variable "i" and for some reason the data was going to a random place leaving empty spots.
I've updated the code and it still goes to random places (don't know why) but doesn't leave any empty spot.
My array is still random if someone can help me.
Imagem = Imagem.replace("[", "");
Imagem = Imagem.replace("]", "");
let ImagemList = Imagem.split(", ");
let Imagens = [];
let contador = 0;
for(let o = 0; o < ImagemList.length; o++){
wfs.readFile(ImagemList[o], "binary", function(err, data) {
Imagens[contador] = (data);
contador++;
if(Imagens.length == ImagemList.length){
socket.emit("ImagemPost", Imagens);
}
});
}

Page Twitter's REST API with Node

I am attempting to get a list of tweets from Twitter with a specific hashtag using Node js. Twitter has is it so that you can only get a maximum of 15 tweets for every request, so I need to make multiple requests if I want a sizable list of tweets. To let Twitter know that you want the next list of tweets, you need to provide a "max_id" variable, which should hold the minumum id of the list of tweets that you got back from the previous request. This process is documented here.
Here is my attempt at doing this:
var hashtag = "thisisahashtag"; // hashtag that we are looking for
var max_id = '';
do {
twitter.search({
q: "#" + hashtag,
result_type: "recent",
max_id: max_id
},
session.accessToken,
session.accessTokenSecret,
function(error, data, response) { // callback
// get the ids of all the tweets from one response and do comparison for smallest one
for(var i = 0; i < data.statuses.length; i++) {
var id = data.statuses[i].id;
if(max_id == '' || id < parseInt(max_id)) {
max_id = id;
}
}
// do something with the data...
}
)
} while(max_id != '0');
I am using the node-twitter-api module to make the requests. This won't work because the outer loop will keep firing off without waiting for the query. Is there a better way to do this?
Twitter lets you request up to 100 tweets at a time. I added a count parameter for this. You should initiate subsequent requests from your callback. That way you will serialize your requests.
function twitterSearch() {
twitter.search({
q: "#" + hashtag,
result_type: "recent",
max_id: max_id,
count: 100 // MAX RETURNED ITEMS IS 100
},
session.accessToken,
session.accessTokenSecret,
function(error, data, response) {
for(var i = 0; i < data.statuses.length; i++) {
var id = data.statuses[i].id;
if(max_id == '' || id < parseInt(max_id)) {
max_id = id;
}
}
// GET MORE TWEETS
if (max_id != '0')
twitterSearch();
}
);
}

Get the result at the right time with node

i am new to node.js, i followed some tutorial.
I don't know how to get the array "result" only when the call in the function end.
app.get('/api/email/check/:email',function (request,response){
var email = request.params['email'];
var result = Array();
for (var i = 0; i < 2; i++) {
existence.check(email, function(err,res){
result[i]=res; console.log({"Result":res});
});
};
response.send(result); // Problem is that i get: []
});
I got the log but the result is an empty array because it's called before the functions ends. Is there a nice way to resolve this ? without counting the "i".
You can put
response.send(result);
out of the for loop.
Because response.send() is a async method so before the for loop ends, response has ended before.

handling asynchronous call backs in nodejs

I am newbie to nodejs.It's very hard to handle callbacks at nodejs level. I have code like this,
getItems(request,function(jsonObject){
var itemData={};
var itemDetails=new Array();
for(var i=0;i < jsonObject.length;i++){
getItemDetails(jsonObject[i].value.item_id,function(jsonObject){
itemDetails.push(jsonObject);
});
}
itemData["itemDetails"]=itemDetails;
response.contentType("application/json");
response.send({"data":itemData});
});
while executing the above code, the for loop is continuing with out getting callback from getItemDetails method and response sent to client. My requirement is the loop will wait until getting the call back from the getItemDetails then response should send.
I have tried with process.nextTick(), but i am unable to find where i have to use that process.nextTick().. Please anybody provide suggestions.
Thanks in advance.
You need to send the response only after you get all the items, so modify your code like so:
getItems(request,function(jsonObject) {
var itemData = {},
itemDetails = [],
itemsLeft = len = jsonObject.length,
i;
function sendResponse(itemDetails) {
itemData["itemDetails"] = itemDetails;
response.contentType("application/json");
response.send({ "data": itemData });
}
for (i = 0; i < len; i++) {
getItemDetails(jsonObject[i].value.item_id, function(jsonObject) {
itemDetails.push(jsonObject);
// send response after all callbacks have been executed
if (!--itemsLeft) {
sendResponse(itemDetails);
}
});
}
});
Note: I've used itemLeft here since it's a more generic way to solve these kind of problems, but Ianzz approach is also ok since you can compare the length of the two arrays.
You can't get the loop to wait, but you can modify your code to get the behavior you are expecting:
getItems(request,function(outerJsonObject){
var itemData={};
var itemDetails=new Array();
for(var i=0;i < outerJsonObject.length;i++){
getItemDetails(jsonObject[i].value.item_id,function(innerJsonObject){
itemDetails.push(innerJsonObject);
if (itemDetails.length == outerJsonObject.length) {
// got all item details
itemData["itemDetails"]=itemDetails;
response.contentType("application/json");
response.send({"data":itemData});
}
});
}
});

Resources