how to pass variable from callback function to function call? - javascript

Here i am sending sensor data to database using simple javascript (johnny five)
using this code
var five = require("johnny-five");
var pg = require("pg");
var conString = "pg://admin:raja#localhost:5432/data";
var client = new pg.Client(conString);
function call(n)
{
client.connect();
client.query("INSERT INTO sensordata (event) VALUES (n);");
}
var board = new five.Board();
board.on("ready", function() {
var sensor = new five.Sensor.Digital(2);
sensor.on("change", function() {
var n = this.value;
call(n);
});
});
My question is can i pass the streaming data variable n in the sensor call back function to call method.

I think, what you're looking here is a simple query templating, supported by all sql clients:
client.query("INSERT INTO sensordata (event) VALUES ($1);", n);
This way you'll be able to pass the value of n variable to your SQL query.
Update: And you don't have to call client.connect() before every call to client.query. You should only call it once to establish DB connection, after that pg.Client will use it to send all subsequent requests.

Related

Data not returning from async function with database connection

The goal is to call a function from my main script that connects to a database, reads a document from it, stores pieces of that document in a new object, and returns that object to my main script. The problem is I cannot get it all to work together. If I try one thing, I get the results but my program locks up. If I try something else I get undefined results.
Long story short, how do I open a database and retrieve something from it to another script.
The program is a quiz site and I want to return the quiz name and the questions.
const myDb = require('./app.js');
var myData = myDb.fun((myData) => {
console.log(myData.quizName);
});
Here is the script that tries to open the database and find the data
const { MongoClient } = require("mongodb");
const {mongoClient} = require("mongodb");
const uri = connection uri goes here but my name is hard coded into it at the moment so I removed for privacy
const client = new MongoClient(uri);
const fun = async (cback) => {
try {
await client.connect();
const database = client.db('Quiz-Capstone');
const quizzes = database.collection('Quiz');
const query = {quizName: "CIS01"};
const options = {
sort: {},
projection: {}
};
const quiz = await quizzes.findOne(query, options);
var quizObject = {
quizName: quiz.quizName,
quizQuestions: quiz.quizQuestions
}
//console.log(testOb);
} finally {
await client.close();
cback(quizObject);
}
}
fun().catch(console.dir);
module.exports = {
fun: fun
}
UPDATE: Still stuck. I have read several different threads here about asynchronous calls and callbacks but I cannot get my function located in one file to return a value to the caller located in another file.

Using Node.js to find the value of Bitcoin on a webpage at real time

I'm trying to make a .js file that will constantly have the price of bitcoin updated (every five minutes or so). I've tried tons of different ways to web scrape but they always output with either null or nothing. Here is my latest code, any ideas?
var express = require('express');
var path = require('path');
var request = require('request');
var cheerio = require('cheerio');
var fs = require('fs');
var app = express();
var url = 'https://blockchain.info/charts/';
var port = 9945;
function BTC() {
request(url, function (err, res, body) {
var $ = cheerio.load(body);
var a = $(".market-price");
var b = a.text();
console.log(b);
})
setInterval(BTC, 300000)
}
BTC();
app.listen(port);
console.log('server is running on '+port);
It successfully says what port it's running on, that's not the problem. This example (when outputting) just makes a line break every time the function happens.
UPDATE:
I changed the new code I got from Wartoshika and it stopped working, but im not sure why. Here it is:
function BTCPrice() {
request('https://blockchain.info/de/ticker', (error, response, body) => {
const data = JSON.parse(body);
var value = (parseInt(data.USD.buy, 10) + parseInt(data.USD.sell, 10)) / 2;
return value;
});
};
console.log(BTCPrice());
If I have it console.log directly from inside the function it works, but when I have it console.log the output of the function it outputs undefined. Any ideas?
I would rather use a JSON api to get the current bitcoin value instead of an HTML parser. With the JSON api you get a strait forward result set that is parsable by your browser.
Checkout Exchange Rates API
Url will look like https://blockchain.info/de/ticker
Working script:
const request = require('request');
function BTC() {
// send a request to blockchain
request('https://blockchain.info/de/ticker', (error, response, body) => {
// parse the json answer and get the current bitcoin value
const data = JSON.parse(body);
value = (parseInt(data.THB.buy, 10) + parseInt(data.THB.sell, 10)) / 2;
console.log(value);
});
}
BTC();
Using the value as callback:
const request = require('request');
function BTC() {
return new Promise((resolve) => {
// send a request to blockchain
request('https://blockchain.info/de/ticker', (error, response, body) => {
// parse the json answer and get the current bitcoin value
const data = JSON.parse(body);
value = (parseInt(data.THB.buy, 10) + parseInt(data.THB.sell, 10)) / 2;
resolve(value);
});
});
}
BTC().then(val => console.log(val));
As the other answer stated, you should really use an API. You should also think about what type of price you want to request. If you just want a sort of index price that aggregates prices from multiple exchanges, use something like the CoinGecko API. Also if you need real-time data you need a websocket-based API, not a REST API.
If you need prices for a particular exchange, for example you're building a trading bot for one or more exchanges, you;ll need to communicate with each exchange's websoceket API directly. For that I would recommend something like the Coygo API, a node.js package that connects you directly to each exchange's real-time data feeds. You want something that doesn't add a middleman since that would add latency to your data.

(Javascript Node.js) How to get varibles from a IIFE

Please see my code below:
I am trying to assign the recordset to a variable, can use index.js to call this variable out.
I am able to console.log the recordset. But when I call this IIFE, it is always says undefined.
var mssql = require('mssql');
var dbcon = require('./dbcon');
var storage = (function () {
var connection = new mssql.Connection(dbcon);
var request = new mssql.Request(connection);
connection.connect(function (recordset) {
request.query('select getdate()', function (err, recordset) {
console.dir(recordset);
});
connection.close();
});
})();
module.exports = storage;
index.js
var storage = require('./storage');
"AMAZON.HelpIntent": function (intent, session, response) {
storage(function (recordset){
var speechOutput = 'Your result is '+recordset;
response.ask(speechOutput);
});
However, I can't get the recordset. I got "Your result is {object, object}. "
that's because the IIFE is executing right away, try returning a function instead and then executing that function when you import that module,
var storage = (function(mssql, dbcon) {
return function() {
var connection = new mssql.Connection(dbcon);
var request = new mssql.Request(connection);
connection.connect(function(recordset) {
request.query('select getdate()', function(err, recordset) {
console.dir(recordset);
});
connection.close();
});
}
})(mssql, dbcon);
and I don't understand why you need the IIFE, why don't you just assign the function to the variable?
If you're trying to assign the variable "recordset" to "storage" then this will never work as "connection.connect" is an asynchronous function, and in that case you should think about callback functions or promises.
Update
Based on your request, here's an implementation with a callback function and how it's used
var mssql = require('mssql');
var dbcon = require('./dbcon');
var storage = function(callback) {
var connection = new mssql.Connection(dbcon);
var request = new mssql.Request(connection);
connection.connect(function(recordset) {
request.query('select getdate()', function(err, recordset) {
if(!err && callback){
callback(recordset);
}
connection.close();
});
});
}
module.exports = storage;
// --------------------------------------------------
// implementation in another module
var storage = require("module_path"); // (1)
var answer;
storage(function(recordset){ // (2)
answer = recordset;
console.log(answer); // actual data, (3)
// implement your logic here
});
console.log(answer); // undefined (4)
// --------------------------------------------------
How this code works:
- You start by calling the storage method and sending it a callback method.
- The whole point of the callback function is that you won't wait for the result, your code will actually continue working at the same time that the storage method is connecting to the database and trying to get the data, ans since db operations are much slower, line(4) will execute before line(3).
- The flow of work will be as follows:
line (1)
line (2)
line (4)
line (3) at sometime in the future when the data is retrieved from database
- To see this more clearly, try doing this at the last line,
setTimeout(function(){console.log(answer);}, 3000);
This will wait for sometime until the data comes back;

how to store a mongodb array of collections inside an indexedDB

Hello I want to build a local database for my phonegap so user can use it offline.
I have this in angular function that creates a database.
function Database() {
return {
create: function (itemDocs) {
var db = null;
var request = indexedDB.open("myDB", 1);
request.onsuccess = function (event) {
db = event.target.result;
console.log("DB loaded successfully");
};
request.onerror = function (event) {
console.log(event)
};
request.onupgradeneeded = function (event) {
db = event.target.result;
console.log("DB initiliazed / created");
//create collections
db.createObjectStore("items", {keyPath: "_id"});
//create documents
var transaction = db.transaction(["items"], "readwrite");
var items = transaction.objectStore("items");
items.add(itemDocs);
};
}
}
}
The itemDocs holds a mongoDB collection (which is an array of objects) and I want to store that collection inside indexedDB database the problem im having is that I'm getting this annoying error.
Uncaught InvalidStateError: Failed to execute 'transaction' on 'IDBDatabase': A version change transaction is running.
Use var transaction = event.target.transaction instead of var transaction = db.transaction(...);
A full answer is rather lengthy. Briefly, you don't want to create a new transaction in onupgradeneeded. There is already an active transaction available for you.

node.js eventListener not listen

i'm a noob of node.js and i'm following the examples on "Node.js in action".
I've a question about one example :
The following code implements a simple chat server via telnet. When i write a message, the script should send message to all connected client.
var events = require('events');
var net = require('net');
var channel = new events.EventEmitter();
channel.clients = {};
channel.subscriptions = {};
channel.on('join',function(id,client){
this.clients[id] = client;
this.subscriptions[id] = function(senderId,message){
if(id != senderId){
this.clients[id].write(message);
}
};
this.on('broadcast',this.subscriptions);
});
var server = net.createServer(function(client){
var id = client.remoteAddress+':'+client.remotePort;
client.on('connect',function(){
channel.emit('join',id,client);
});
client.on('data',function(data){
data = data.toString();
channel.emit('broadcast',id,data);
});
});
server.listen(8888);
But when i try to connect via telnet and send a message it doesn't work.
Thanks
A couple issues I noticed. See the comments in the code.
var events = require('events');
var net = require('net');
var channel = new events.EventEmitter();
channel.clients = {};
channel.subscriptions = {};
channel.on('join',function(id, client) {
this.clients[id] = client;
this.subscriptions[id] = function(senderId,message) {
if(id != senderId)
this.clients[id].write(message);
};
//added [id] to "this.subscriptions"
//Before you were passing in the object this.subscriptions
//which is not a function. So that would have actually thrown an exception.
this.on('broadcast',this.subscriptions[id]);
});
var server = net.createServer(function(client) {
//This function is called whenever a client connects.
//So there is no "connect" event on the client object.
var id = client.remoteAddress+':'+client.remotePort;
channel.emit('join', id, client);
client.on('data',function(data) {
data = data.toString();
channel.emit('broadcast',id,data);
});
});
server.listen(8888);
Also note: If a client disconnects and another client sends a message then this.clients[id].write(message); will throw an exception. This is because, as of now, you're not listening for the disconnect event and removing clients which are no longer connected. So you'll attempt to write to a client which is no longer connected which will throw an exception. I assume you just haven't gotten there yet, but I wanted to mention it.

Categories