How to query data from InfluxDB using Node.js - node.js

I am working on a project where I have an InfluxDB bucket that has a measurement of elapsedtime and a tag of service. I want to query Influx to be able to get all datapoints in the last 1 hour for foobar as the service. Ideally I will add a time measurement later on which I could use to base my 1 hour off since the system that gets the elapsed time and the system that writes it to Influx are different and have about 1-2 minutes of latency between them.
I have taken some example code from here and I have gotten this which is nearly identical since I am unsure of what needs to change and could not understand the documentation (head's cloudy?).
The end goal of this is to be able to have a graph that shows the elapsedtime for a service when I query my application - which queries Influx. I would like to be able to query based off a preset list of service and times but that is application side of things and I am giving here as context to what I'd like this to result in eventually.
...
variables that define bucket, url, org and token
...
const queryApi = new InfluxDB({url, token}).getQueryApi(org)
const fluxQuery =
`from(bucket:"${bucket}") |> range(start: 0) |> filter(fn: (r) => r._measurement == "elapsedTime")`
console.log('*** QUERY ROWS ***')
// Execute query and receive table metadata and rows.
// https://v2.docs.influxdata.com/v2.0/reference/syntax/annotated-csv/
queryApi.queryRows(fluxQuery, {
next(row: string[], tableMeta: FluxTableMetaData) {
const o = tableMeta.toObject(row)
console.log(
`${o._time} ${o._measurement} in '${o.location}' (${o.example}): ${o._field}=${o._value}`
)
},
error(error: Error) {
console.error(error)
},
complete() {
console.log('\nFinished SUCCESS')
},
})
When I run this I get an error about an extra value in there however I'd expect the example to have correct code so maybe I am missing something I need to update?
next(row: string[], tableMeta: FluxTableMetaData) {
^
SyntaxError: Unexpected token ':'
at wrapSafe (internal/modules/cjs/loader.js:992:16)
at Module._compile (internal/modules/cjs/loader.js:1040:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
at Module.load (internal/modules/cjs/loader.js:941:32)
at Function.Module._load (internal/modules/cjs/loader.js:782:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
at internal/main/run_main_module.js:17:47

The issue ended up being that the code I had copied was TypeScript which as you can imagine doesn't work in a JavaScript file. Silly mistake on my end

Related

Is this intended behaviour of custom errors?

I'm currently in the process of remaking the maze package from five years ago in ES2015. I am making a custom error, named LengthError, which will be thrown if an argument of type Function does not have a specified length. I just want to know if this is the intended behaviour because I am running this locally, or if this will carry over to production for when others might use this function?
Error:
LengthError: Argument 'adjacent' must be of length 2
/home/runner/maze/index.ts:6
throw new LengthError('Argument \'adjacent\' must be of length 2')
^
LengthError: Argument 'adjacent' must be of length 2
at null.generate (/home/runner/maze/index.ts:6:13)
at Object.<anonymous> (/home/runner/maze/index.ts:37:1)
at Module._compile (node:internal/modules/cjs/loader:1101:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47
index.ts:
import { LengthError } from './errors';
export default function generate(nodes: number[], adjacent: Function, choose: Function) {
if (adjacent.length !== 2) {
try {
throw new LengthError('Argument \'adjacent\' must be of length 2')
} catch(e: any) {
console.error(e.name + ': ' + e.message + '\n' + e.stack)
}
}
let node: number = choose(nodes);
let stack = [node];
let maze = new Map();
for (node of nodes) {
maze.set(node, []);
}
while (node) {
let neighbors = nodes.filter(other => !maze.get(other).length && adjacent(node, other));
if (neighbors.length) {
const neighbor = choose(neighbors);
maze.get(node).push(neighbor);
maze.get(neighbor).push(node);
stack.unshift(neighbor);
node = neighbor;
} else {
stack.shift();
node = stack[0];
}
}
return maze;
}
generate([], function a() {}, function b() {});
errors.ts:
class LengthError extends Error {
constructor(message: string) {
super(message);
this.message = message;
this.name = "LengthError";
}
}
export { LengthError };
Again, is this code going to display a similar error in production (where the custom error shows twice) and will it point to the same line in my file?
I just want to know if this is the intended behaviour because I am running this locally, or if this will carry over to production for when others might use this function?
Yes, this is how it works, both locally and in production. This is what nodejs does when there's an uncaught exception using try/catch.
When you throw errors, you're supposed to have code somewhere else that catches them and turns them into the desired behavior.
In the error message, the first line is the statement of the error. The second set of lines are the "stack trace" that show where in the code this originated from, including the current call stack at the time of the error.
Note, in your code that catches exceptions, you may want to log the exception and perhaps even log the track trace and then "handle" the error in some way that makes sense for your application (such as return a user-friendly error message or in an API, return some documented API error or in an http request, return a 4xx or 5xx error status).

Error while trying to serialize a Qlik Sense app into a JSON object

I am trying to serialize a Qlik Sense app (.qvf file) into a JSON object.
For that I am passing the .qvf file in the below code as directed here - https://github.com/mindspank/serializeapp
The main reason behind this exercise is to save the JSON in Gitlab for version control since we cannot save .qvf in Git for version control as it is a binary file.
var qsocks = require('qsocks')
var serializeapp = require('serializeapp')
qsocks.Connect()
.then(global => global.openDoc('Executive D:\Users\ddas7071\Documents\Qlik\Sense\Apps\NewDeb.qvf'))
.then(app => serializeapp(app))
.then(result => console.log(result))
serializeapp = require('serializeapp')
const enigma = require('enigma.js')
const WebSocket = require('ws')
enigma.getService('qix', {
schema: require(`./node_modules/enigma.js/schemas/qix/12.67.2.json`),
session: {
host: 'localhost',
port: 4848,
secure: false
},
createSocket: (url) => new WebSocket(url)
})
.then(qix => qix.global.openDoc('Executive
D:\Users\ddas7071\Documents\Qlik\Sense\Apps\NewDeb.qvf'))
.then(app => serializeapp(app))
.then(result => console.log(result))
But while running the code (in windows), I am running into the below problem -
D:\Users\ddas7071\Desktop\Novartis_TechnicalDetails\myfile.js:12
enigma.getAttribute('qix', {
^
TypeError: enigma.getAttribute is not a function
at Object. (D:\Users\ddas7071\Desktop\Novartis_TechnicalDetails\myfile.js:12:8)
[90m at Module._compile (internal/modules/cjs/loader.js:1158:30)[39m
[90m at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)[39m
[90m at Module.load (internal/modules/cjs/loader.js:1002:32)[39m
[90m at Function.Module._load (internal/modules/cjs/loader.js:901:14)[39m
[90m at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)[39m
[90m at internal/main/run_main_module.js:18:47[39m
Though I understand the error, but not sure how to resolve it.
Note - All the pre-requisites are being taken care of already.
qsocks is not supported from some time and serializeapp is using qsocks under the hood.
If you want to connect to Qlik Engine please the official package - enigma.js. But there is no JS package (as far as i know that can extract the objects information.
But ...
There is a CLI (official) that can do this for you (havent tested it myself) - corectl. Corectl have option to unbuild the app into separate json/yaml files which you can then put under version control
The description for the unbuild command
Extracts generic objects, dimensions, measures, variables, reload script and connections from an app in an engine into separate json and yaml files. In addition to the resources from the app a corectl.yml configuration file is generated that binds them all together. Passwords in the connection definitions can not be exported from the app and hence need to be handled manually. Generic Object trees (e.g. Qlik Sense sheets) are exported as a full property tree which means that child objects are found inside the parent´s json (the qChildren array).

Read file and write file JSON

In this, I am trying to make a hit counter where every time someone visits my site the variable will be read from the views.json file one is added to the number and then the .json will be updated with the new number. However when I tested it in a repl.it project I got an error saying
ReferenceError: writeFileSync is not defined
at /home/runner/hit-counter/index.js:6:1
at Script.runInContext (vm.js:133:20)
at Object.<anonymous> (/run_dir/interp.js:156:20)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32) at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
I don't know what this means if you know please tell me and how I may be able to fix it.
the reply project link:https://hit-counter.cohense.repl.run/
The JavaScript (ES6)
const fs = require('fs');
let views = fs.readFileSync('views.json');
views = JSON.parse(views);
views.total++;
let data = JSON.stringify(views, null, 2);
writeFileSync("views.json", data, finished);
function finished(err) {
if (views = JSON.parse(views)) {
console.log("Your view has been accounted for!")
} else {
console.error("Error occured please reload the page =(")
}
};
the JSON
{
"totalViews": 1
}
You can do like this, just fixed some errors.
Oh, you should use writeFileSync, to avoid that the file will not be edited at same time.
The question is, why don't you use a DB? It's a lot faster and fix concurrency writes.
var fs = require('fs')
var data = fs.readFileSync('views.json')
var views = JSON.parse(data);
console.log(views);
views.total = views.total + 1;
var data = JSON.stringify(views, null, 2)
writeFileSync("views.json", data, ()=>{
console.log("Your View Has Been Accounted For!")
})
I found out what I did wrong I didn't use fs.
writeFileSync("views.json", data, finished);
When I just needed to do
fs.writeFileSync("views.json", data[,finished]);

Make Discord Bot for node.js JSON.parse() error : undefined:1

I want to make Discord Bot.
I use Node.js and Discord api.
my error :
C:\----\----\Desktop\SiiNaBot>node app.js
undefined:1
SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at Object.<anonymous> (C:\Users\Lin\Desktop\SiiNaBot\app.js:7:21)
at Module._compile (module.js:573:30)
at Object.Module._extensions..js (module.js:584:10)
at Module.load (module.js:507:32)
at tryModuleLoad (module.js:470:12)
at Function.Module._load (module.js:462:3)
at Function.Module.runMain (module.js:609:10)
at startup (bootstrap_node.js:158:16)
at bootstrap_node.js:598:3
my cord :
//Calling the pakage
const Discord = require('discord.js');
const bot = new Discord.Client();
const fs = require('fs');
// JSON Files
let userData = JSON.parse(fs.readFileSync('Storage/userData.json', 'utf8')); // This calls the JSON file.
//Listener Event : Message Received ( This wiil run every time a message is recived)
bot.on('message', message => {
//Variables
let sender = message.author; // The person who sent th message
let msg = message.content.toUpperCase(); // Takes the message, and makes it all uppercase
let prefix = '>' // The test before commands, you can set this to what ever you want
//Event
if(!userData[sender.id + message.guild.id]) userData[sender.id + message.guild.id] = {} // This creates a json file for their user + guild, if one is not made already.
if(!userData[sender.id + message.guild.id].money) userData[sender.id + message.guild.id].money = 1000; // This creates a money object for them if they start out with, you can change this to whatever you want.
fs.writeFile('Storage/userData.json', JSON.stringify(userData), (err) => {
//This writes the changes we just made to the JSON file.
if (err) console.error(err);
})
// Commends
//Ping
if (msg === prefix + 'PING'){
message.channel.send('Pong!') // Sends a message to the chanel, with the contens: "Pong!"
}
})
// This code runs when the bot turns on
bot.on('ready', () => {
console.log('Economy Launched...')
})
// Login
bot.login('I`ll write code my bot token');
//Don`t let people see this code, people can control your bot, including the servers your bot has admin on.
My Folder
Structure of my folder here
I think this error is this line
let userData = JSON.parse(fs.readFileSync('Storage/userData.json', 'utf8'))
and...
fs.writeFile('Storage/userData.json', JSON.stringify(userData), (err) => { //This writes the changes we just made to the JSON file.
if (err) console.error(err);
})
this line. but i don`t know how can i fix this cord.
How can i do?
The error message is arising from the first, not the second, as it attempts to parse your JSON data. You can identify this in the call stack of your error here:
at Object.<anonymous> (C:\Users\Lin\Desktop\SiiNaBot\app.js:7:21)
It was during processing of your app.js, line 7, character position 21, which corresponds to the JSON.parse( ... ) method.
Your error, however, is not with this application code : that is fine thus far! The complaint concerns the JSON data file that its consuming, hence the error message: "Unexpected end of JSON input" (this is the error message being emitted from your parse() method).
Furthermore, its parsing through your JSON line-by-line, and its seeking the end of the JSON object definition, but the file ends first! What was the problem in that JSON file? Well, what is missing is being reported as the undefined of the error message, and just like the position in the call stack, the :1 identifies this as missing content at character position 1 - that is, it was expecting to find a character at its cursor positioned at the first character of that line, but instead it encounters the marker instead.
Your JSON object definition in Storage/userData.json needs to enclosed in properties with your customised data and therefore, I can be pretty sure you have omitted to terminate the definition of that JSON object, and what is likely missing on the last line is:
}
So, simply by adding this last line in your userData.json will likely solve your data input file problem.
(See, for example, this gist and compare the content/structure of your userData.json with their config.json described in Setup)
I used the exact same tutorial as you are using. There is a very simple way to solve this problem. Just go into your userData.json and put in "{}" I had the exact same problem with the exact same error message and this fixed it.

Node 5.10 spread operator not working

According to the docs, the latest node (Node 5+) should support the spread operator by default, like so:
const newObj = {
...oldObj,
newProperty: 1
}
And I have node 5.10.1 installed (e.g. that's what 'node -v' tells me). But I am still getting this error:
c:\[myprojectfolder]>node index.js
c:\[myprojectfolder]\index.js:21
...oldObj,
^^^
SyntaxError: Unexpected token ...
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:387:25)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Function.Module.runMain (module.js:447:10)
at startup (node.js:146:18)
at node.js:404:3
What am I missing?
The array spread syntax is supported, but the object spread syntax is not - this is most likely due to it not being finalized as part of the ECMAScript spec yet (it was originally planned for inclusion in ES7/ES2016, but it got bumped back, if I recall correctly).
Your options in the meantime are either to use a transpiler (such as Babel, with the transform-object-rest-spread plugin), or if that feels like overkill, you can use the new built-in Object.assign function. The object spread syntax is effectively just syntax sugar around Object.assign - the example in your question could be expressed like so:
const newObj = Object.assign({}, oldObj, {
newProperty: 1
});
Note the empty object as the first argument; the properties from the rest of the passed objects get merged into it, with those furthest to the right of the function call taking priority. It may seem more intuitive to simply have oldObj as the first argument, but this doesn't have quite the same effect - it would mutate the existing oldObj as well as returning it. Having an empty object as the target leaves oldObj unchanged.
Update: As of Node 8.6, object spread syntax is supported.
Update 2: Object spread syntax has finally made its way through the proposal process, and will be part of the ES2018 spec.
What you tried to use is called object spread and is not part of the es2015 specification. Node only supports the regular spread in function calls and array literals. Unfortunately not even array destructuring is supported yet, although they link to the MDN page which describes both structuring and destructuring use of ....
You can use Object.assign instead:
const newObj = Object.assign({}, oldObj, {
newProperty: 1
});
That's works in Node.js 8.5.0.
Example:
var oldObj = {
oldProperty: 0
}
var newObj = {
...oldObj,
newProperty: 1
}
console.log('Old Object: ' + JSON.stringify(oldObj, null, ' '))
console.log('New Object: ' + JSON.stringify(newObj, null, ' '))
Output:
Old Object: {
"oldProperty": 0
}
New Object: {
"oldProperty": 0,
"newProperty": 1
}
Screenshot from IDE Debug Console:

Resources