How to do execute a query loop inside of another query loop - javascript

so my question is, how i can achieve this: I have an array of dates and an array of locations, i want to iterate the array of dates, and for each date, execute some query's, them iterate the whole array of locations doing an query for each item and them return an JSON response with the data.
P.S. I am using TypeOrm and i am also novice

If you've got two arrays, and you want to loop one inside of the other, then... just do that.
var locations = ['Paris','St Louis','Moscow'];
var dates = ['wednesday', 'thursday', 'friday'];
async function run(locations, dates) {
let results = [];
for (let location of locations) {
for (let date of dates) {
console.log(`${location} - ${date}`);
const newResults = await query(location, date);
results = results.concat(newResults);
}
}
return results;
}
run(locations, dates);
edited to include async query example

Related

Use array of invoice numbers to create invoice objects within which each invoice number from the initial array serves as id property

Building a script in google apps script.
I get values from an invoice data sheet with multiple lines per invoice so as to account for line items.
My progress so far has been to extract individual invoice numbers from the column (each invoice number occurs as many line items the individual invoice has).
The array todaysInvoices looks like this: [35033817, 35033818, 35033819, 35033820, 35033821]
Now, I need a way to create an object for each of these invoice numbers that has different properties (such as invoiceDate and customerName etc.). The initial invoice number as in the array should thereby be assigned as 'id' property to the new invoice object.
I need help to use objects in javascript.
If you require additional information, please let me know.
Below is a screenshot of a simplified version of my order sheet:
This is a clipping of my order sheet. Before and after the shown columns there are many more with more details but the hierarchies of information are already in the image
Below is the code I have so far:
const orderSheet = SpreadsheetApp.openById('SPREADSHEETID').getSheetByName('SHEETNAME');
const invoiceTemplate = DriveApp.getFileById('DOCUMENTID');
const tempFolder = DriveApp.getFolderById('FOLDERID');
const invoiceData = orderSheet.getRange(4,7, orderSheet.getLastRow() - 1, 57).getDisplayValues().filter(function (rows){ return rows[0] === 'INVOICED'});
const invDataRepo = SpreadsheetApp.openById('SPREADSHEETID2');
var timestamp = new Date();
function printBulkInvoices() {
logLineItems ();
var todaysInvoices = uniqueInvIDs ();
todaysInvoices.sort();
todaysInvoices.map(String);
//fetchInvData (todaysInvoices);
Logger.log (todaysInvoices)
}
function fetchInvData (invoiceIDs) {
let invoices = {
}
Logger.log(invoices)
invoiceIDs.forEach
}
function fetchLineItems (invoiceDataArray) {
}
// send array of todays unique invoice numbers (later all inv data?) to invdata sheet and log them
function logTodaysInvoices (invIDArr){
invIDArr.forEach
invDataRepo.getSheetByName('invdata').getRange(invDataRepo.getSheetByName('invdata').getLastRow()+1,1,invIDArr.length,1).setValue(invIDArr);
}
// return an array of unique invoice ids from todays invoice data
function uniqueInvIDs (){
let singleArray = invoiceData.map(row => row[5]);
let unique = [...new Set(singleArray)];
return unique;
}
//log incoicedata to invdatarepo-sheet 'lineitems'
function logLineItems (){
invDataRepo.getSheetByName('lineitems').getRange(invDataRepo.getSheetByName('lineitems').getLastRow()+1,2,invoiceData.length,invoiceData[0].length).setValues(invoiceData);
}
It's hard to say exactly what you need since we cannot see your Invoice Data Sheet.
But here's something that might give you a start:
let iobj = {idA:[]};
[35033817, 35033818, 35033819, 35033820, 35033821].forEach((id => {
if(!iobj.hasOwnProperty(id)) {
iobj[id]={date: invoiceDate, name: customName, items:[]};
iobj.idA.push(id);//I find it handy to have an array of object properties to loop through when I wish to reorganize the data after it's all collected
} else {
iobj[id].items.push({item info properties});//I am guessing here that you may wish to addition additional information about the items which are on the current invoice
}
});
Javascript Object
To follow up from your question:
Your loop to collect object data would start to look something like this:
function getInvoiceData() {
const ss = SpreadsheetApp.getActive();
const ish = ss.getSheetByName('Invoice Data');
const isr = 2;
const hA = ish.getRange(1, 1, 1, ish.getLastColumn()).getValues()[0];
let idx = {};//object return head index into row array based on header title which in this case I assume invoice number is labeled 'Invoicenumber'
hA.forEach((h, i) => {idx[h] = i});
const vs = ish.getRange(isr, 1, ish.getLastRow() - isr + 1, ish.getLastColumn()).getValues();
let iobj = { idA: [] };
vs.forEach(r => {
if (!iobj.hasOwnProperty(r[idx['invoicenumber']])) {
iobj[r[idx['invoicenumber']]] = { date: r[idx['invoicedate']], name: r[idx['customername']], items: [] };
iobj.idA.push(r[idx['invoicenumber']]);
} else {
iobj[r[idx['invoicenumber']]].items.push({ iteminfoproperties:'' });
}
});
}

How to convert mysql row of data into a javascript array? Node.js app

First, I'm a newbie. No doubt, I've made some simple errors.
Using Node.js with MySQL Database, I'm building a basic web app that allows users to login. Once they've logged in they will be brought to their profile page and are displayed results of a quiz they've done in the form of a bar chart.
I want covert a row of mysql data into an array.
const mysql = require('mysql');
const dbconfig = require('/config/database');
const connection = mysql.createConnection(dbconfig.connection);
connection.query('USE ' + dbconfig.database);
// Create an array of scores for each category depedning on the user who's
// loggedin.
var category1scoreQuery =
"SELECT c1q1, c1q2, c1q3, c1q4, c1q5, c1q6, c1q7, c1q8
FROM nodejs_login.assessment_score
AS a JOIN users as u ON a.respondent_id = u.user_respondent_id
WHERE a.respondent_id = user.user_respondent_id;";
connection.connect(function(err){
if (err) throw err;
connection.query(category1scoreQuery, function(err, result, fields) {
if (err) throw err;
Object.keys(result).forEach(function(key){
var cat1Array = result[key];
// want to return array e.g. ["45/60", "60/60", "40/40","30/40","15/20",
// "30/40", "30/60", "20/40"];
console.log(cat1Array);
})
})
});
// I want to convert it to an array to parse the array of strings into
// totalUserScore over maxCategoryScore
var i;
var userCategoryScore1 = 0;
var maxCategoryScore = 0;
for(i=0; i < cat1Array.length;i++){
var splitScore = cat1Array[i].split("/");
console.log(splitScore);
myQuestionScore = parseInt(splitScore[0], 10);
userCategoryScore1 += myQuestionScore;
console.log(userCategoryScore);
maxQuestionScore = parseInt(splitScore[1]);
maxCategoryScore = maxCategoryScore + maxQuestionScore;
console.log(maxCategoryScore);
}
This is what I am actually getting which doesn't allow me to loop through.
RowDataPacket {
c1q1: '15/60',
c1q2: '15/60',
c1q3: '10/40',
c1q4: '10/40',
c1q5: '5/20',
c1q6: '10/40',
c1q7: '15/60',
c1q8: '10/40' }
This should work for you:
const RowDataPacket= {
c1q1: '15/60',
c1q2: '15/60',
c1q3: '10/40',
c1q4: '10/40',
c1q5: '5/20',
c1q6: '10/40',
c1q7: '15/60',
c1q8: '10/40' }
const values=Object.values(RowDataPacket);
console.log(values)
Reference[1st part] : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values
Description:
The Object.values() method returns an array of a given object's own enumerable property values, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).
For the second part, to calculate the total scores:
//using the values array from first part
const scores=values.reduce((accum,value)=>{
const splitValues=value.split('/')
return {
score:accum.score + parseInt(splitValues[0]),
maxScore:accum.maxScore + parseInt(splitValues[1]),
}
},{score:0,maxScore:0})
console.log(scores)
Reference[2nd part]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
Description:
The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in a single output value.
This is fairly common problem when interacting with a database through javascript. To get what you want you can try using JSON library like this:
usersRows = JSON.parse(JSON.stringify(result));
Also this isn't exactly related to your question but it's something that made my life a lot easier when I was doing this: consider using the node Promisify module to transform your queries into promises (from here: https://www.npmjs.com/package/util-promisify). That way instead of having to use callbacks like you are doing your code would look something like this:
var results = await connection.query(category1scoreQuery);
//Process results here
Again this is only a suggestion but something that I found was very useful.
Cheers!

Is there a way to make the firestore search results into an array?

I am trying to make an array from the search results of a query search in firestore.
The results from a query search from something like
docRef.get().then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
var dataArray = doc.data();
var arrayOutputs = [dataArray];
var name = arrayOutputs[0].Name;
console.log(name);
});
});
Will return all of the results where there are three results given which it shows up but I am trying to put each of the Objects into one array. Pulling the search results separately if needed and using it for a "for loop".
thank you
The OP code assigns arrayOutputs to a single element array on each iteration. To get an array of results, map over the returned docs, getting data() from each...
docRef.get().then(function(querySnapshot) {
let allDocData = querySnapshot.docs.map(doc => doc.data());
console.log(JSON.stringify(allDocData));
});
Edit Same idea with a for loop rather than map...
docRef.get().then(function(querySnapshot) {
let allDocData = [];
querySnapshot.forEach(function(doc) {
allDocData.push(doc.data());
});
console.log(`we found ${allDocData.length} docs as follows...`);
console.log(JSON.stringify(allDocData));
});
If you want to push the result to an array, do:
docRef.get().then(function(querySnapshot) {
var myArray = [];
querySnapshot.forEach(function(doc) {
myArray.push(doc.data());
});
});

Access the nested value in JSON without looping through it

This is my JSON, I want to directly get the zipCodes values from the JSON without looping through the JSON. How can I do it?
countries:[
{
name:'India',
states:[{
name:'Orissa',
cities:[{
name:'Sambalpur',
zipCodes:{'768019','768020'}
}]
}]
}
]
I think you are looking for
countries[0].states[0].cities[0].zipCodes
Please note, this works for the above JSON as there is only 1 country in countries array and same as for states and cities. However, if there are more than 1 country, state or city then, you will have to iterate to extract information until and unless you know the exact index.
As this is not an associative array, your option is only to use indexes like this:
countries[x].states[y].cities[0].zipCodes
Where x would be each representation of state in your array, in case, of course, that you have more than one.
Similarly y would be each state in each state in each country, in case you have more of those and you can do the same for cities if you need to.
EDIT:
Here's how you can iterate the array:
for(var c in countries)
{
var name = countries[c].name;
if (name === "CountryIAmLookingFor")
{
var statesList = countries[c].states;
for (var s in statesList)
{
var stateName = statesList[s].name;
.....
}
}
}
You can keep iterating until you find the country, state, and city you need, then extract the zipCodes from there as shown in the previous code snippet.
Without "looping"
You can do this crazy trick (not saying this is the best way, but this way you aren't looping through the JSON):
var myData = { 'Put Your Data': 'HERE' };
function getCodes(name, data) {
var sv = data.match(new RegExp(name+'([\\S\\s]*?}][\\S\\s]*?}])'))[1].match(/zipCodes":\[(.*?)\]/g), r = [];
sv.forEach(function (item) {
item.match(/\d+/g).forEach(function (sub) {
r.push(+sub);
});
});
return r;
}
getCodes('India', JSON.stringify(myData));
If your data is already string, then you don't need the JSON.stringify. The forEach you see isn't actually "looping" through the JSON. It's already extracted the zip codes and the code just adds the zip codes to the array. . This line:
var sv = JSON.stringify(data).match(new RegExp(name+'([\\S\\s]*?}][\\S\\s]*?}])'))[1].match(/zipCodes":\[(.*?)\]/g), r = [];
is what grabs the zip codes, it gets something like:
["zipCodes":["768019","768020"]"]
The next line:
item.match(/\d+/g)
will grab the numbers outputting something like:
["768019", "768020"]
The loop just adds the zip-codes to another array
With looping
You're better off looping through the JSON:
var myData = {}, // Your data
zips = [];
myData.countries.forEach(function(i) {
if (i.name === 'India') {
i.states.forEach(function(j) {
j.cities.forEach(function(l) {
l.zipCodes.forEach(function(m) {
zips.push(m);
});
});
});
}
});
//use "zips" array
PERFORMANCE AND SPEED TESTS
After testing copying an array about 500MB (half a gig) took about 30 seconds. That's a lot. Considering an extremely large JSON would be about ~5MB, looping through a little over 5MB of JSON takes about 0.14 seconds. You should never worry about speed.
Here's my "trick" for avoiding explicit iteration. Let JSON.parse or JSON.stringify do the work for you. If your JSON is in string form, try this:
var array = [];
JSON.parse(jsonString, function (key, value) {
if (key === "zipCodes") {
array = array.concat(value);
}
return value;
});
console.log(array); // all your zipCodes
Suppose your Json is like
countries =[
{
name:'India',
states:[{
name:'Orissa',
cities:[{
name:'Sambalpur',
zipCodes:768019768020
}]
},{
name:'mumbai',
cities:[{
name:'rea',
zipCodes:324243
}]
}]
}
]
So now we use MAP it will give you ZipCode of every cities
countries.map(function(s){
s.states.map(function(c){
c.cities.map(function(z){
console.log(z.zipCodes)
})
})
})
OR
If you use return statement then it will give you 2 array with two zip code as per over JSON
var finalOP = countries.map(function(s){
var Stalist = s.states.map(function(c){
var zip = c.cities.map(function(z){
return z.zipCodes
})
return zip
})
return Stalist
})
console.log(finalOP)

Javascript Array of Objects and Unique Values

I have an array of objects that looks like this:
[
{"name":"Andrea","from":"USA","Food":"Candy"},
{"name":"Matt","from":"Taiwan","Food":"Chicken"},
{"name":"Roddy","from":"USA","Food":"Rice"},
{"name":"Andy","from":"Great Britain","Food":"Steak"},
];
Is there a way to get the list of all countries from the array above, and get rid of the repeated ones?
So from the list above, the list I am to obtain is:
["USA", "Taiwan", "Great Britain"]
Thank you!
Just loop over people and insert unique countries in a new array. Here is an example.
var countries = [];
var people = [
{"name":"Andrea","from":"USA","Food":"Candy"},
{"name":"Matt","from":"Taiwan","Food":"Chicken"},
{"name":"Roddy","from":"USA","Food":"Rice"},
{"name":"Andy","from":"Great Britain","Food":"Steak"},
];
for (var i = 0, l=people.length; i < l; i++) {
if(people[i] && people[i].from) {//ensure country exists
if (countries.indexOf(people[i].from) == -1) {//ensure unique
countries.push(people[i].from);
}
}
}
Yet another variant with reduce
var arr = [
{"name":"Andrea","from":"USA","Food":"Candy"},
{"name":"Matt","from":"Taiwan","Food":"Chicken"},
{"name":"Roddy","from":"USA","Food":"Rice"},
{"name":"Andy","from":"Great Britain","Food":"Steak"},
];
var countries = arr.reduce(function(acc, cur){
if(!acc.map[cur.from]){
acc.map[cur.from]=true;
acc.result.push(cur.from);
}
return acc;
}, {result:[], map:{}}).result;
var arr = [
{"name":"Andrea","from":"USA","Food":"Candy"},
{"name":"Matt","from":"Taiwan","Food":"Chicken"},
{"name":"Roddy","from":"USA","Food":"Rice"},
{"name":"Andy","from":"Great Britain","Food":"Steak"},
];
var countries = arr.reduce(function(acc, cur){
if(!acc.map[cur.from]){
acc.map[cur.from]=true;
acc.result.push(cur.from);
}
return acc;
}, {result:[], map:{}}).result;
document.getElementById('countries').innerHTML = countries.join();
<span id="countries"></span>
If you are already using the excellent Lodash library, the following will do it for you neatly in one line:
var uniqueCountries = _(dataArray).pluck('from').unique().value();
UnderscoreJS has similar functionality using chaining.
For D3.js, the following will do it:
var uniqueCountries = d3.set(dataArray.map(function (x) { return x.from; })).values();
Without doing the unique-ifying on the server and returning that data separately, there is no way to get around looping through all records at least once to do this. For 1000 records or so, though, this will still be very fast.
For plain JS, see other answers.
I'd loop over the Array and put the country into an array if it is not yet inside that array.

Categories