How do I display resultset from async await - json

I am trying to display the resultset of this query as a json list. However only the top record is being displayed. How do I return multiple records from async await.
This is the output I want
This is the output I get

You're destructuring the first item from the array, don't do it if you want the full result set.
const arr = [{a:'a'}]
const [a] = arr
console.log(a)

Related

Sorting array function over JSON loops like crazy

so I'm trying to deal with a function but it's looping like crazy and I can't figure out why.
Basically, I want to loop over a json file, retrieve every "average" value and sort it in a new array, so when I call the function ranking(countries[iso].average), it returns the position in the array.
It's actually working but the json file is way bigger, and when I console.log(rank) in the loop, it returns more than 27K messages.
ranking = (n) => {
var rank = [];
if (n) {
for (let iso in countries) {
var newvar = countries[iso].average;
rank.push(newvar);
rank.sort(function(a, b) {
return b - a;
});
}
return rank.indexOf(n) + 1
}
};
{"countries":{"US":{"name":"United States of America","ranking":"","average":13.12,"flag":"https://restcountries.eu/data/usa.svg","altNames":["US","USA"],"reports":1302,"cases":0,"deaths":299692,"recovered":23232,"lat":38,"lng":-97,"deltaCases":2,"deltaDeaths":3,"deltaRecovered":0,"casesPerOneMillion":2,"deathsPerOneMillion":903,"totalTests":22323,"testsPerOneMillion":3434,"population":345},"IN":{"name":"India","ranking":"","average":10.22,"flag":"https://restcountries.eu/data/ind.svg","altNames":["IN","Bhārat"],"reports":1016,"cases":9796992,"deaths":142222,"recovered":9290834,"lat":20,"lng":77,"deltaCases":null,"deltaDeaths":null,"deltaRecovered":646,"casesPerOneMillion":7068,"deathsPerOneMillion":103,"totalTests":151632223,"testsPerOneMillion":109402,"population":1295210000},"RU":{"name":"Russian Federation","ranking":"","average":13.21,"flag":"https://restcountries.eu/data/rus.svg","altNames":["RU","Rossiya"],"reports":1321,"cases":2597711,"deaths":45893,"recovered":2059840,"lat":60,"lng":100,"deltaCases":28585,"deltaDeaths":613,"deltaRecovered":26171,"casesPerOneMillion":17797,"deathsPerOneMillion":314,"totalTests":81564365,"testsPerOneMillion":558804,"population":146599183}}}
Thanks for any help on this
I believe that what you may be trying to do is sort by the field called average for countries in the iso. So you have some lookup called countries and there are ISOs there like I imagine: 'US'. Then Rank is an array of all these countries.
The problem I see is that you have sort happening within the for loop.
The way you explained the problem seems like 2 different steps. One retrieve the average, then AFTER that sort by the average.
If really all you want is the averages in the array: you can do like
const averages = Object.values(countries).map(country => country.average)
That single step will get you all the averages into a single array.
Then next you can sort using the same function you posted. (The key is to brake that into a second loop not a nested loop:
averages.sort((a, b) => b - a)
// now sorted
But in case you wanted to keep the rest of the data you can do that pretty easily as well:
Something more like:
const countriesSortedByAverage = Object.values(countries).sort((a, b) => b.average - a.average)
If you really need the ISO you can also do the same with Object.entries but it might be even easier to provide the iso inside the country Object.
To determine the rank for all countries you can easily add that to (if you wanted) and have that be the principal country Object:
const RANKED_LIST_OF_COUNT = countriesSortedByAverage.map((countryObj, rank) => ({ ...countryObj, rank }))
If you want to further restore it to the CountriesByISO object:
const COUNTRIES_BY_ISO_WITH_RANK = Object.assign({}, ...RANKED_LIST_OF_COUNT.map(country => ({ [country.ISO]: country}))
)

How can I get the value from a Knex query using max?

I have a very simple Knex query against a MySQL table to find the maximum value of the id column:
const maxId = await knex('some_table').max('id').first()
But this returns a TextRow object with a single, oddly named property. From a console.log:
TextRow { 'max(`id`)': 99 }
Is there an easy way for me to get the value, or do I have to use object property notation like this:
const idValue = maxId['max(`id`)']
It appears the easiest answer is to alias the result, as in the second example shown here:
const maxIdQuery = await knex('some_table').max('id as maxId').first()
console.log(maxIdQuery.maxId) // shows the value
Alternate syntax:
const maxIdQuery = await knex('some_table').max('id', { as: 'max_id' })
console.log(maxIdQuery[0]['max_id'])
Hope this helps someone in the future.

IN clause in mysql nodejs

I have a simple nodejs application which executes the following query.
select * from User where userid in (?)
The userids i get is a JSON array send from client side. How can i use that in this select query ? I tried
1. As itself but not working.
2. Convert this to Javascript array, not working
If you are using node module like mysql, the 2nd approach should work.
var query=select * from User where userid in (?);
var data=['a','b','c'];
var queryData=[data];
conn.query(query, queryData, function (err, results) {})
According to the documentation, "Arrays are turned into list, e.g. ['a', 'b'] turns into 'a', 'b'". So this approach should work (I have used it practically).
If you pass an array to the parameter it works with node mysql2. Parameters are already passed as arrays, so your first parameter needs to be an array [[1,2,3]].
select * from User where userid in (?)
const mysql = require('mysql2/promise');
async function main(){
let db = await mysql.createPool(process.env.MYSQL_URL);
let SQL = 'select * from User where userid in (?)';
let [res, fields] = await db.query(SQL, [[1,2,3]]);
console.log(res)
return res;
}
main().then(() => {process.exit()})
Revisiting this, since the original approach on the question is valid, but with some caveats. If your only escaped argument is the one on the IN clause, then you have to specify it as nested array; something like: [['usrId1', 'usrId2', 'usrIdN']]. This is because the un-escaping functionality expects an array, replacing each '?' with the corresponding array element. So, if you want to replace your only '?' with an array, that array should be the first element of all arguments passed. If you had more than one '?', the syntax is more intuitive, but at the end consistent and the same; in this case, you could have your arguments similar to: ['myOtherArgument1', 'myOtherArgument2', ['usrId1', 'usrId2', 'usrIdN'], 'myOtherArgument3']
Something like this could work!
// get your possible IDs in an array
var ids = [1,2,3,4,5];
// then, create a dynamic list of comma-separated question marks
var tokens = new Array(ids.length).fill('?').join(',');
// create the query, passing in the `tokens` variable to the IN() clause
var query = `SELECT * FROM User WHERE userid IN (${tokens})`;
// perform the query
connection.query(query, ids, (err, data) => {
// do something with `err` or `data`
});
You can do like this:
select * from User where userid in (?,?,?,?)
var array = [];
array.push(value);
array.push(value);
array.push(value);
array.push(value);
then use array as parameter that should be bind.
// get query string data with commas
var param=req.params['ids'];
//damy data var param = [1,2,3,4,5];
var array = params.split(",").map(Number);
//Note in select query don't use " and ' ( inverted commas & Apostrophe)
// Just use ` (Grave accent) first key off numeric keys on keyboard before one
con.query(`select * from TB_NAME where COL IN(?)`,[array],(err,rows,fields)=>{
res.json(rows);
});
let val = ["asd","asd"]
let query = 'select * from testTable where order_id in (?)';
connection.query(query, [val], function (err, rows) {
});
In Node, you need to put array in the array.
Update: Please see this answer. It is the correct way to do what is asked in the question.
The methods I have tried are:
Expand JSON array to a string in the required format. Concatenate it with query using '+'. (Beware of SQL injections)
Dynamically add '?' using length of JSON array holding user ids. Then use the array to provide user ids.
Both works. I then changed my logic with a better approach so now i don't need then 'in' clause anymore.

Getting data from thunk in node, mysql, koa

I want to get some data out of my MySQL database using Koa and the mysql node package. I was looking at co-mysql, but the readme suggests to use thunkify directly. So I did the following:
const query = thunkify(connection.query.bind(connection));
Which seems to work, as I now can do:
app.use(function * main() {
const races = yield query(
"SELECT * FROM `races` where '2016-01-19' between start_date and end_date"
)(function(err, rows) {
// rows is the data I need
});
});
However, I cannot find a way to return/yield the row data from the thunk into my races variable. I log it, and it displays the correct data, but when I try to pass it back, it always returns undefined. I've tried a couple of ways from inside the callback, but I can't seem to figure it out:
return rows
yield rows (made the callback a generator function)
return yield rows
...
I'm often getting: TypeError: You may only yield a function, promise, generator, array, or object, but the following object was passed: "undefined"
races is an array because you are using thunkify for query. co returns an array for any thunks that call their callback with more than one value (ie. callback(null, 1, 2, 3) returns [1, 2, 3].
If you were to Promisify query instead, races will be assigned to the first returned value only, which appears to be inline with what you're looking for.
Here's a code example showing it in practice:
var co = require("co")
var promisify = require("bluebird").promisify
var thunkify = require("thunkify")
function async(callback) {
callback(null, 1, 2, 3)
}
var p = promisify(async)
var t = thunkify(async)
co(function*() {
let x = yield p()
let y = yield t()
console.log(x)
console.log(y)
}).then(() => {})
When run, the value of x will be 1 and the value of y will be the array [1, 2, 3].
You can run it with Tonic here: https://tonicdev.com/56ab7cfc879afb0c002c1d49/56ab7cfc879afb0c002c1d4a

Raw SQL in Django

I am try to perform a RAW SQL query in django. I am having some trouble getting the fetchall result to output a list of the distinct items in a column.
So I am hoping to get a list of all the items in a column.
class TableObject (object):
def __init__ (self, Kingdom):
SQL_str_Table = "SELECT DISTINCT column_title FROM sql_table"
cursor.execute(SQL_str_Table, [])
listOfReturns = cursor.fetchall()
for each in listOfReturns:
item = each
when I try a print out of "item" I get:
"bound method TableObject.write of mysite.forms.veiws.TableObject object at 0x03E5EE70"
So my question is how do I get the fetchall result into a list.
If you want to get a flat list of only column_title's then you can do this:
listOfReturns = cursor.fetchall()
listOfReturns_flat = [i for i in listOfReturns if i[0]] #remove empty results if any