JavaScript + MySQL: use fields as parameter in result - javascript

I'm quite new to JavaScript and I have the following issue:
I have a Node.JS server on which a webclient can connect and execute functions. One function is to look into a MySQL database and gather information.
The query is done right and I obtain the correct raw information as for example:
Here is my code:
So I correctly get the column names using the fields (fields[0].name = Count_0)variable and I am able to get the correct value using the result (result[0].Count_0 = Gray).
However, I am unable to merge the two lines in order to create the list of colors using something like this in a loop: result[0].fields[0].name = Gray
Is there an easier way to do this or not ?
Thanks,
Nicola.

In Javascript, you can use the [] operator to access a variably-named property in an object.
Instead of using result[0].fields[0].name, use
result[0][fields[0].name]
You won't get any runtime errors for accessing a property that doesn't exist, so you'll want to check whether that value is undefined before using it somewhere else.

It seems you want to get the color. If so, you can get the color by this
let color = result[0][fields[0].name];
The idea is use fields[0].name as key of result[0].
This is the breakdown of above single line.
let key = fields[0].name;
let color = result[0][key];

Related

Cannot put a variable inside channels.get() on discord.js

I've been trying to do some workaround on this thing but it just drives me crazy. The way I see it, it should work just fine but there is something going wrong with it... I hope I am not just really tired and missed a very easy mistake.
Anyway here is the thing. It's something pretty easy to do. an event is activated and then the algorithm below is supposed to read a certain database where I have the ids of the channels I want to send to stored, and it does one loop for each of those ids, outputting a different id on each loop,
(note: I am not doing it inside a client.on("message) event)
let channel = client.channels.get(dbresult)
channel.send(`test`);
This part was supposed to run 2 times with 2 separate numbers on the dbresult variable(since i have just 2 numbers on the database).
Now, when I run this part with just the id number alone and not the dbresult variable like this:
rows.forEach(function(row){
//let dbresult = row.newsid.toString()
let channel = client.channels.get(`0123456789`)
channel.send(`test`);
})
the script works just fine, but when I use the dbresult variable, it gives me this error
channel.send(`test`);
^
TypeError: Cannot read property 'send' of undefined
Now these are the things I've tried:
Putting a console.log(dbresult) just inside the foreach() block. It reads the ids just fine!
Making dbresult a string (as you can see) and also I've tried not converting it into a string too
Just Because I was desperate I even tried this: channel.send(${dbresult}), just in case.
Things that work:
The things I want to get triggered outside this part of the script are just fine, the script always gets activated successfully.
The script always reads each and every one of the ids of the channel. By removing the insides of "foreach" function and putting a console.log(dbresult), I saw that it outputs the different ids I want it to output.
Here is the whole script:
let db = new sqlite.Database('./databases/Serverinfo', sqlite.OPEN_READWRITE | sqlite.OPEN_CREATE);
const sql = 'SELECT newsid FROM news';
db.all(sql, function(error,rows){
if (rows.length <= 0){
return;
}
if (error){
throw error;
}
rows.forEach(function(row){
let dbresult = row.newsid.toString()
console.log(dbresult)
let channel = client.channels.get(dbresult)
channel.send(`test`);
})
db.close();
})
Any help is appriciated of course
If you are using discord.js v.12 you need to use the cache collection.
And yes, the id you want to use needs to be a string.
let channel = client.channels.cache.get(dbresult);
https://discord.js.org/#/docs/main/stable/class/ChannelManager
What you might consider doing is checking if the channel was found before you try to send something.
EDIT: The problem after updating comes from the fact that you store the channelID in your database as an INT which brings the following problem: Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as integers.
What that means is that it doesn't store the ID correctly because it is too large, we are talking in the Quadrillions here. This could happen either at your database or when you import the number into your code. Without knowing your DB setup I can't tell.
Example:
683328323304292410 // the actual ID of the channel
683328323304292400 // the INT that is stored
To fix this you have two options and both need to be implemented in your database.
You can either convert the datatype for the row which stores the channelID to bigINT or convert it when you import the ID source
You can store the channelID as a string in the first place. (probably the easier solution)

Return Array of Data using Google Assistant from Firebase

The structure I have for my firebase database is like this:
fruits:
apple,5
banana,6
I want to put apple and banana in an array so that when i give a command to Google Assistant, it would give me apple, 5 and banana, 6. The code I have is like the one below:
function handleCommand(agent) {
return admin.database().ref('Fruits').child().once("value").then((snapshot) =>{
var i;
var fruitlist=[];
//puts each snapshot child of 'Fruit' in an array
snapshot.forEach(function(item) {
var itemVal = item.val();
fruitlist.push(itemVal);
});
//outputs command in google assistant
for (i=0; i < fruitlist.length; i++) {
agent.add(fruitlist[i]);
}
})
The default response is "not available".
I get the following in the execution logs:
Firebase.child failed. Was called 0 aruguments. expects at least 1.
I do not know which argument to put inside the Firebase.child. if i want all fruits to be "spoken" by Google Assistant. Below is a picture of my firebase structure.
The error looks like the one below:
What I am currently doing now to just output the fruits are manually entering each child in the code like this and removed the ".child" in the return statement:
Which gives me the output below which is also what I want to see but using arrays as the solution I am using now is very much hardcoded:
As the error message suggests, and as you surmise, the child() call expects a parameter - in particular, the name of the child node you want to get information from. However, since you want all the children of the "Fruits" node - you don't need to specify it at all. The child() call just navigates down through the hierarchy, but you don't need to navigate at all if you don't want to.
The snapshot you get back will have a value of the entire object. In some cases, this can be pretty large, so it isn't a good idea to get it all at once. In your case, it is fairly small, so not as big a deal.
On the JavaScript side, you can now handle that value as an object with attributes and values. Your original code didn't quite do what you said you want it to, however - you're getting the value, but ignoring the name (which is the attribute name or key). You can iterate over the attributes of an object in a number of ways, but I like getting the keys of the object, looping over this, getting the value associated with the key, and then "doing something" with it.
While I haven't tested the code, it might look something like this:
function handleCommand(agent) {
return admin.database().ref('Fruits').once("value").then((snapshot) =>{
// Get an object with all the fruits and values
var fruits = snapshot.val();
// Get the keys for the attributes of this object as an array
var keys = Object.keys( fruits );
// Iterate over the keys, get the associated value, and do something with it
for( var i=0; i<keys.length; i++ ){
var key = keys[i];
var val = fruits[key];
agent.add( `The number of ${key} you have are: ${val}` );
}
})
While this is (or should be) working Firebase and JavaScript, there are a couple of problems with this on the Actions on Google side.
First, the message returned might have some grammar problems, so using your example, you may see a message such as "The number of Apple you have are: 1". There are ways to resolve this, but keep in mind my sample code is just a starter sample.
More significantly, however, the call to agent.add() with a string creates a "SimpleResponse". You're only allowed two simple responses per reply in an Action. So while this will work for your example, it will have problems if you have more fruit. You can solve this by concatenating the strings together so you're only calling agent.add() once.
Finally, you may wish to actually look at some of the other response options for different surfaces. So while you might read out this list on a speaker, you may read a shorter list on a device with a screen and show a table with the information. Details about these might be better addressed as a new StackOverflow question, however.

AlaSQL set result to variable for use elsewhere

I'm fairly new to JavaScript and AlaSQL, so sorry if this is obvious.
I'm trying to save the result of my AlaSQL query to a variable so I can use it elsewhere in my code. As a bit of context, I'm querying a CSV file, and I'm wanting to get the max, min and a certain row of a particular column, so I can then use this elsewhere. At the moment I'm just trying it on the max aspect.
<script>
alasql.promise('VALUE OF SELECT MAX(PM1) FROM CSV("http://localhost:8000/assets/interpolated.csv", {separator:","})').then(function(res){console.log(res); document.getElementById("testingId5").innerHTML = res}).catch(function(err){console.log('Error:', err);});
</script>
This produces a result and logs it in the console, and shows it onscreen, but I want to set it to a variable to be able to use too!
I've tried just adding var test = res; within the .then(function(res){}) part, but with no luck.
Thanks in advance.

Updating Data Set query after parameter input in BIRT

How can I change or update a data set's query after a parameter has been passed in BIRT report designing?
Detailing:
I've got a query that looks like this:
WHERE ?
That parameter marker can hold different values, after user input parameter, it would look like this e.g.:
WHERE column_name = 1
or
WHERE column_name = 2
or even
WHERE column_name IN (1,2)
I created a Report Parameter(RP) for that Data Set Parameter(DSP) and after trying for hours, I couldn't get to change it.
I tried:
Creating all sorts of javascript expressions on both, RP and DSP
Creating a RP that would change the value of the first RP and back to previous step
Editing the Property Binding, though I couldn't figure it out how exactly it should be done.
Just to make it clear, I'm designing a report and not integrating the runtime to an existing application.
I hope this is clear enough, I'm still editing the question so if you need more information just let me know.
Thanks
Assuming that you are on an Oracle DB (other systems may behave differently) you should be aware that a bind variable (in JDBC speech: the question mark) can replace a scalar value only, e.g. a string or a number.
But you want something like a list of numbers as input.
Thus a bind variable won't help you in this case.
Probably the easiest way to achieve what you want is this:
In your query, write:
WHERE column_name in (1) -- $REPLACE_THIS$
Note that I am using a comment in the query as a marker.
Then, in the query's beforeOpen event, modify the query text like this:
// construct a comma-separated string representation of your list
// based on your report parameter (exercise left to the reader)
// var replacement = my_to_sql_csv(params["my_report_parameter"].value);
// for demonstration use:
var replacement = "1,2";
// modify the `IN` expression inside the SQL
this.queryText = this.queryText.replaceAll("(1) -- $REPLACE_THIS$", "(" + replacement + ")";
That's it.

Dynamically Add JS to an ASP.NET page and get results from the JS

Here's my issue:
Client(s) give me separate JS files which will run a check of some sort on the user's system (Browser type, are cookies enabled?, etc.) and a list of acceptable values to be returned from this check.
I want to run through each JS file when a user visits the site and compare the results to the list of acceptable values, then alert the user if they pass these requirements or not.
I'm currently using RegisterClientScriptBlock() to add the JS to the client's page, so it's being run, but I'm having issues getting the result value from the JS back to ASP.NET in order to do the comparison.
I've tried using hidden fields that the JS will dump the value to and ASP.NET will read from, but I'm having difficulty generating the hidden fields on demand (since I have no idea how many Js files the client could have) and have them work in the ASP.NET code.
Any help, or suggestions in the right direction would be awesome, thanks!
What I would do is have the results be an array of KeyValuePair objects that you would then serialize to JSON. So you create the javascript object type like so:
function KeyValuePair(key, value){
this.Key = key;
this.Value = value;
}
Then you would build up an array of KeyValuePairs like so:
//This array is declared in the global scope
var ValueArray = new Array();
function someFunction(){
//this assumes that the key and value variables are created earlier in the function
var valueToStore = new KeyValuePair(key, value);
ValueArray[ValueArray.length] = valueToStore;
}
So at the point when you are done with all your checks you would use the json2 serializer to serialize the array to json for storage in your hidden field.
var jsonToSaveToHiddenField = JSON.stringify(ValueArray);
//Logic to store resulting json and trigger the serverside evaluation here
On the server side you would use JavascriptSerializer to deserialize your json to an array of KeyValuePairs. Here is the msdn doc on that: JavaScriptSerializer Class Reference
So with this approach you only need one hidden field. So you don't need to dynamically create it which should simplify the server side retrieval quite a bit.
The above should work with minimal changes however I haven't run this through a compiler so there might be some minor syntax errors preset.

Categories