I'm trying to get the results pulled from the API inserted into a database. It returns a SQL error when the program is run. It seems I'm not having this sent in the right syntax and I cant seem to to get it to do so. Is there a better way to do this?
var request = require('request');
var mysql = require('mysql');
var replace = require ('Regexp')
var url = 'https://api.nicehash.com/api?method=stats.provider.workers&addr=3Hwm6i8aefzHhJTbEGtSJeR6tZCJXqY7EN';
//connect to database
var con = mysql.createConnection({
host: 'localhost',
user: 'xxxxx',
password: 'xxxxx',
database: 'xxxxx',
table: 'workerstats'
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});
const requestHandler = (request, response) => {
response.end(workerstats)
}
request.get({
url: url,
json: true,
headers: {'User-Agent': 'request'}
}, (err, res, data) => {
if (err) {
console.log('Error:', err);
}
else if (res.statusCode !== 200)
{
console.log('Status:', res.statusCode);
}
else {(!err && data && data.result && data.result.workers)
var workerstats = JSON.stringify(data.result.workers);
var wsclean = workerstats.replace(/[&\/\\#+()$~%'*?<>{}]/g,'')
.replace(/"a":/g,'');
};
console.log(wsclean);
var sql = "INSERT INTO 'workerstats' (workers, accepted, uptime, xnsub, difficulty, zone, algo) ?", wsclean;
con.query(sql, [workerstats], function (err, result) {
if (err) throw err;
console.log("Number of records inserted: " + result.affectedRows);
}
);
})
EDIT: Okay so after hours of tinkering, I 'think' I've made progress, but that silly A: has got me again. Its viewing as an object, and SQL is rejecting it. Though I thought (Though obviously improperly) I converted it to string. This is the amended code. Please forgive the formatting, it wasnt playing nice.
request.get({
url: url,
json: true,
headers: { 'User-Agent': 'request' }
}, (err, res, data) => {
if (err) {
console.log('Error:', err);
}
else if (res.statusCode !== 200) {
console.log('Status:', res.statusCode);
}
else {
(!err && data && data.result)
var data = JSON.parse(data.result);
var responseJson = JSON.stringify(data.response);
var query = connection.query('INSERT INTO table SET column=?', responseJson, function (err, result) {
if (err) throw err;
console.log('data inserted');
});
}
});
It returns the following error:
undefined:1
[object Object]
SyntaxError: unexpected token o in JSON at postion 1
Awesome. So somewhere I did something stupid, or improperly. In the raw API that object Object appears like: {"a":"158.01"} - How do I convert that to a string, when I thought I already did? Id also like to eliminate the 'a' and the ':' entirely as im not sure how to process that into SQL and its unneeded information.
When you setup json: true in the request option, You no longer have to perform JSON.parse(data.result), you directly access the data as object. Therefore the error, because JSON.parse({ a: 1}) call the toString method, and the result [object Object] its not valid JSON.
Note: You convert the data.result.workers to a string. I think you should leave it as an array for it to work.
con.query(sql, data.result.workers, function (err, result)
Related
I am using Typescript, Express, PostgresDB.
Here is my code for connecting to the database cluster.
import { Pool } from "pg";
const myPool = new Pool({
host: `${process.env.DATABASE_URL}`, //somedb.abc.us-east-1.rds.amazonaws.com
database: `${process.env.DATABASE_NAME}`, //dbName
user: `${process.env.DATABASE_USER}`, //dbUser
password: `${process.env.DATABASE_PASSWORD}`, //dbPassword
port: 5432
});
myPool.connect();
Here is my post route:
const router = express.Router();
router.post("/item/new", async (request, response) =>{
try{
const { itemTitle } = request.body;
const myItem = await myPool.query(`INSERT INTO items VALUES('${itemTitle}')`), (resp, err) =>{
if(err){
return err;
}
return resp;
});
return response.status(201).json({message: myItem});
}catch(err){
return response.status(400).json({message: `${err}`});
}
});
When I send the request, I get the following response with a 201 status code, but nothing
is inserted into the database:
{
"message": {}
}
It's because you're sending the callback function with the wrong argument's order. The first argument for the callback is error, not result.
It should be like this:
client.query('SELECT NOW() as now', (error, result) => {
if (error) {
console.log(error.stack)
} else {
console.log(result.rows[0])
}
})
documentation.
You can try to print the query that you are passing to find the error.
The reason is that you are concatenating a json object with string which is wrong, instead try this:
`INSERT INTO items(col1, col2) VALUES(${itemTitle.col1}, ${itemTitle.col2})`
I am trying to fetch data from mongodb's collection. My code is executing only single row data in json format. But when I console log my data I can see all the row data.
const mongoose = require('mongoose');
const AllMinisters = require('../models/allMinisters');
var db;
var mongodb = require("mongodb");
// Initialize connection once
mongoose.connect("******", { useNewUrlParser: true }, function(err, database) {
if(err) return console.error(err);
db = database;
// the Mongo driver recommends starting the server here because most apps *should* fail to start if they have no DB. If yours is the exception, move the server startup elsewhere.
});
exports.getAllMinisters = (req,res,next)=>{
db.collection("users").find({}, function(err, docs) {
if(err) return next(err);
docs.each(function(err, doc) {
if(doc) {
console.log(doc);
var response = {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: doc
}
res.end(JSON.stringify(response));
}
});
});
};
This output in JSON as
However the console report shows all
How can I show all row data in JSON
You have docs.each in your code that will iterate over all the doc you get from the find() query (which is an array) and inside that each block you are sending the response i.e, res.end(JSON.stringify(response));, which executes immediately for the first record and hence you get a single object as a response instead of array.
To return the array you need to put res.end(JSON.stringify(response)); outside the each() loop with toArray function. You can even remove the each() loop if that is not required. So, your code will be something like:
exports.getAllMinisters = (req, res, next)=>{
db.collection('users').find({}).toArray(function (err, docs) {
if (err) {return next(err);}
docs.each(function (err, doc) {
if (doc) {
//code for single doc
console.log(doc);
}
});
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(docs));
});
};
I'm using Node.js/Express.js to install data to my MySQL DB.
Inserting data works fine, but returning success / fail gives me an error.
TypeError: Cannot read property 'status' of undefined
This is my code:
var crud = {
newProject: function (req, res, callback) {
db.query('INSERT INTO projects SET ?', req.body, function(err, res) {
// This is where it fails
if(err){
return res.status(500).json({error: err});
} else {
return res.status(200).json({success: 'Insert row success'});
}
});
},
}
// Express routing
app.post('/project/*', crud.newProject);
What am I not getting right here?
Solution
So this is what I used to make it work (after changing 'res' to 'resp' as suggested):
if (err) throw err;
res.end(JSON.stringify({response: 'Success'}));
Your defining res twice. The express response object is getting overwritten by the data param in your node callback.
Try the following (see comment)
var crud = {
newProject: function (req, res, callback) {
// changed 'res' to 'resp' to avoid collision with Express' 'res' object
db.query('INSERT INTO projects SET ?', req.body, function(err, resp) { // here's your error
// This is where it fails
if(err){
return res.status(500).json({error: err});
} else {
return res.status(200).json({success: 'Insert row success'});
}
});
},
}
// Express routing
app.post('/project/*', crud.newProject);
If you define error-handling middleware functions after the last app.use() in your main configuration
app.use(function (err, req, res, next) {
res.status(500).send(err.message || 'Internal server error.')
})
You can use the next callback as a catchall error handler, so the above would then become
var crud = {
newProject: function (req, res, callback) {
db.query('INSERT INTO projects SET ?', req.body, function(err, resp) {
if (err) return callback(err);
return res.json({success: 'Insert row success'});
});
},
}
// Express routing
app.post('/project/*', crud.newProject);
res.json() by default should add a 200 Success code to the response header. Ideally you would want to inspect the resp data param from the node callback after checking the state of err to properly handle the response and proceed accordingly, especially if you are dealing with last evaluated records associated with a continuation token usually provided in the response which some DBALs and APIs do for you and some don't. Either way you will want to be sure additional recursion isn't necessary to fetch remaining records before responding successfully.
Looks like the res object is undefined as it is not returning any response after the insert. You may return a new object like:
return {
status: 200,
json: {success: 'Insert row success'}
}
I am trying to write all the documents in a mongoDB collection to my web site. My code:
mongoClient.connect('mongodb://localhost:27017/database', function(err, db) {
if (err) throw err
var cursor = db.collection("Users").find();
while(cursor.hasNext()){
res.write(cursor.next())
}
res.end()
But I get the error first argument must be a string or buffer. Why is that? How can I parse the above data into a string then?
Try the following snippet, Am assuming resp is http response.
mongoClient.connect('mongodb://localhost:27017/database', function(err, db)
{
if (err) throw err
console.log("Connected successfully to server");
db.collection("Users").find({}).toArray(function(err, dbres) {
console.log("select : ", dbres);
db.close();
resp.writeHead(200, { "Content-Type": "application/json"});
resp.write(JSON.stringify(dbres));
resp.end();
});
}
I'm using Node.JS with Express (and ejs for the views) and I want to call two API endpoints to render them in the same page and use the data. I've tried doing it with async but I get
ECONNRESET: Request could not be proxied!
This is my code
app.get('/profile', function(req, res) {
async.parallel([
function(next) {
var query = req.query.search;
var url = '1st url' + query;
var request = require('request');
request(url, function(error, body) {
var data = JSON.parse(body);
next(error, data);
});
},
function(next) {
request('2nd url', function(error, tlist) {
var list = JSON.parse(tlist);
next(error, list);
});
}], function(err, results) {
if (!err && results.statusCode == 200)
var data = results[0];
var list = results[1];
res.render('profile', {data: data, list: list});
});
});
Unsure about Cloud9, but if the issue is around parsing data, there's a couple of things here.
You should handle the error on each request before you attempt to parse; if parse throws an exception, your callback won't be executed:
request(url, function(error, body) {
if (error) return next(error);
var data = JSON.parse(body);
next(null, data);
});
You should probably also have a try/catch around the parse, and execute your callback with an error if there's an exception:
request(url, function(error, body) {
if (error) return next(error);
var data;
try {
data = JSON.parse(body);
} catch (e) {
return next(new Error('Unable to parse body for ' + url));
}
next(null, data);
});
Finally, your current check for results.statusCode will always return false, since it's an array, so you won't reach the end of the request. I'm guessing this is probably where the problem lies. I would also recommend passing any errors from async on to the Express error handler:
function(err, results) {
if (err) {
// pass to Express error handler...
}
var data = results[0];
var list = results[1];
res.render('profile', {data: data, list: list});
});