I've written a program that listens to a public MQTT channel and prints any incoming messages ---> this works well
I have a bit of code in the same program that can read and write from a local database I have ---> this works well
I want to insert the message that is printed from the MQTT channel INTO a table in my database.
I've looked around for solutions and tried all sorts, but I can't seem to get anywhere with the solutions and help in the other topics.
Edit: My table is called 'sensors' and it has 1 column called 'value'
EDIT2:
My function:
if (data) {
//do database update or print
console.log("----");
console.log("temp: %s", data);
connection.query('INSERT INTO sensors VALUES ??', [data], function (error, results, fields) {
// When done with the connection, release it.
//connection.release();
console.log(results);
// Handle error after the release.
if (error) throw error;
});
//reset to undefined for next time
data = undefined;
}
Currently fails to write to my table. but it can listen and read fine
Any suggestions?
I fixed my issue. It turned out to be a syntax error
here's the solution
if (data) {
//do database update or print
console.log("----");
console.log("temp: %s", data);
connection.query('INSERT INTO sensors VALUE (?)', data, function (error, results, fields) {
// When done with the connection, release it.
//connection.release();
console.log(results);
// Handle error after the release.
if (error) throw error;
});
//reset to undefined for next time
data = undefined;
}
});
Related
I have the following AJAX that will send the entered data to the node server and the controller will check whether such data exist in the database or not.
If I do enter the data correctly, then everything is working fine.
However, I tried enter anything that the database does not have and it immediately throw an error, causing the server to stop. The error said that I did not handle the event, so I tried with res.json(err) in the controller instead of throw new Error, hoping that the error will be passed back to AJAX under the error key, but it is still not working. The error still gets thrown and the node server terminate itself.
I would like the server to continue and alert to the user that the data that was entered is not in the database but I have no idea why my approach is not correct.
I was thinking of using this SO thread if I'm able to get the error message back first from server side.
jQuery Ajax error handling, show custom exception messages
To solve the server from stopping, I used the code in app.js that was referred from this link
How do I prevent node.js from crashing? try-catch doesn't work
I'm not sure whether should I use the accepted answer for my case.
function createProduct(inputval){
let inputAction = window.location.pathname;
$.ajax({
type: "POST",
url: inputAction,
data: {order: inputval.split('-')[0].trim(), lot: inputval.split('-')[1].substring(0,5)},
success: function(data) {
$('#product').val('');
//Another function to add HTML
display(data);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log("XHR" + jqXHR)
console.log("Status" + textStatus)
console.log(errorThrown)
}
});
}
Controller File
exports.createProduct = function (req, res) {
db.Product.findOne({ "order": req.body.order, "lot": req.body.lot }).exec(function (err, product) {
if (!product || err){
throw new Error("The product entered returns null");
}
res.json(product);
});
};
Main File: app.js
process.on('uncaughtException', function (err) {
console.error(err);
console.log("Node NOT Exiting...");
});
You should use correct status code for your response. I suggest change your controller like below snippet
exports.createProduct = function (req, res) {
db.Product.findOne({ "order": req.body.order, "lot": req.body.lot }).exec(function (err, product) {
if (err){
res.status(500).end();//means internal server error
} else if (!product) {
res.status(404).end();//means product not found
} else {
res.json(product);
}
});
};
I finally figure it out thanks to feedback from other community, so I thought I would just share it here. It's so simple and silly me for neglecting such statement.
First, the code in app.js can just be removed.
Second, based on the answer given by #Milad Aghamohammadi. Instead of just:
res.status(500).end();
Use:
return res.status(500).json({err: "Server error"});
This way, the error is able to be handled by the AJAX error function and the node server will not be terminated from the event loop.
I am currently using angularJS as my frontend framework while expressJS on node.JS to provide the REST API as my backend framework.
For my insertService function in node.JS, after I insert some value into the database, I want to commit and release the connection. However, I am getting the following error:
NJS-032: connection cannot be released because a database call is in progress
These are my commit and release functions:
function doRelease(connection)
{
console.log("before release");
connection.release(
function(err) {
if (err)
console.error(err.message);
});
console.log("after release");
}
function doCommit(connection)
{
console.log("before commit");
connection.commit(
function(err) {
if (err)
console.error(err.message);
});
console.log("after commit");
doRelease(connection);
}
This is how I am calling them:
app.post('/addService', function(req, res)
{
console.log("addService is called");
oracledb.getConnection(
DBconfig,
function(err, connection)
{
if (err) { console.error(err); return; }
connection.execute(
"Insert into mylist Values (MYLIST_ID_SEQUENCE.nextval ,'"+req.body.name+"','"+req.body.description+"')",
function(err, result)
{
if (err) { console.error(err); doRelease(connection); return; }
console.log("added mylist: "+req.body.name);
doCommit(connection);
}
);
}
);
})
This is the print out:
addService is called
before commit
after commit
before release
after release
NJS-032: connection cannot be released because a database call is in progress
How should I handle this issue? Should I sleep for 1 second before calling release? Should I recursively call release until it is successful?
Thanks
Before I answer your question I have to point out that your code is currently open to SQL injection vulnerabilities. Values from end users (in this case from req.body) should not be concatenated into the SQL, they should be "bound" in with bind variables.
Also, you're API will not scale if you're getting one off connections. You should create a connection pool and get connections from the pool.
Finally, you can use autoCommit (in the execute options object) to save an unnecessary round trip.
Now to your question, you have to wait until the commit finishes before releasing the connection. In doCommit, move the call to doRelease so that it's in the callback to connection.commit:
function doCommit(connection) {
console.log("before commit");
connection.commit(function(err) {
if (err) {
console.error(err.message);
}
console.log("after commit");
doRelease(connection);
});
}
On another note, I have a series on building REST APIs you might want to check out. In part 2, on database basics, I show how you can simplify these types of simple statement executions. There are links to the code in GitHub so you should be able to pull it down to see how it works for you.
Getting started with Node.js and Heroku; I am trying to make sense of the following code, in order to build something of my own:
app.get('/db', function (request, response) {
pg.connect(process.env.DATABASE_URL, function(err, client, done) {
client.query('SELECT * FROM test_table', function(err, result) {
done();
if (err)
{ console.error(err); response.send("Error " + err); }
else
{ response.render('pages/db', {results: result.rows} ); }
});
});
});
Where can I find a tutorial or some comments or explanations for that?
Even though I can do some guessing, a good deal of this code is pretty mysterious.
Currently my main concerns are:
What happens if I change the SQL query, replacing it by 'SELECT
count(*) FROM test_table'? How do I then render the result?
What does "done();" do? Is it something I can modify or make use
of?
The parameter "request" is never used. Can it be used for
something at some point?
Before handling heroku, you should first look at tutorials about web application in node.js which will answers your last question.
You can see how works express.js, a web framework.
Then look at node-postgre documentation. You will find your answers about the second question here :
//this initializes a connection pool
//it will keep idle connections open for a 30 seconds
//and set a limit of maximum 10 idle clients
var pool = new pg.Pool(config);
// to run a query we can acquire a client from the pool,
// run a query on the client, and then return the client to the pool
pool.connect(function(err, client, done) {
if(err) {
return console.error('error fetching client from pool', err);
}
client.query('SELECT $1::int AS number', ['1'], function(err, result) {
//call `done()` to release the client back to the pool
done();
if(err) {
return console.error('error running query', err);
}
console.log(result.rows[0].number);
//output: 1
});
});
And finanlly, why don't you just log result output after changing the SQL query and look what you get ?
I'm making a web application using the MEAN framework and MVC design pattern. I am trying to perform a POST request from the Angular front-end for finding a document in my server-side MongoDB (version 2.4.9). The console logs show that the query is successful, but when I try to send the response back to the client, the query result is undefined.
I understand that NodeJS is asynchronous and uses callbacks, but I am having trouble understanding what is wrong with my code. I tried using returns and callbacks but I can't get it working. I'm confused how to use the controller to access the model and have the controller ultimately send the response.
Here is my code to connect to the database (model):
module.exports = {
readDocument : function(callback, coll, owner) {
// Connect to database
MongoClient.connect("mongodb://localhost:27017/tradingpost", function(err, db) {
if (err) {
console.log("Cannot connect to db (db.js)");
callback(err);
}
else {
console.log("Connected to DB from db.js: ", db.databaseName);
//Read document by owner
// Get the documents collection
var collection = db.collection(coll);
// Find document
collection.find({owner: owner}).toArray(function (err, result) {
if (err) {
console.log(err);
} else if (result.length) {
console.log('Found:', result);
} else {
console.log('No document(s) found with defined "find" criteria!');
}
// Close connection
db.close();
return callback(result);
});
}
})
}}
And here is my controller that sends the response:
var model = require('../models/db');
exports.sendRecentPosts = function (req,res) {
// Connect to the DB
// Run query for recent posts
// Close the connection
// Send the data to the client
var result = model.readDocument(dbCallback, "gs", "Mana");
res.end( result );
};
Client's post request:
// Use post for secure queries
// Need recent posts for display
$http.post('/recent').
success(function(responseData) {
$scope.testValue = responseData;
}).
error(function(responseData) {
console.log('Recent posts POST error. Received: ', responseData);
});
Snippet for my express route:
var goodsServices = require('../controllers/gs-server-controller.js');
app.post('/recent', goodsServices.sendRecentPosts);
I have been struggling with this for a long time and searched the forum for solutions but could not find any. Thanks for any feedback.
I do not know why this question has not been answered yet. When I faced the same problem, I learnt that the response to all DB queries are returned after the DB transaction is complete. Try placing db.close() within the success callback response of the find() call.
So this has me banging my head against the desk. Here's the code giving me issues.
SERVER:
client.on('get-online-clients', function () {
connection.query('SELECT CLIENTS FROM DB', function(err, rows, fields) {
if (err) throw err;
client.emit('update-clients', rows);
console.log(rows);
});
});
CLIENT:
socket.on('update-clients', function(rows) {
console.log(rows);
});
Now my issue is that when the console.log(rows) output is printed server side, in the node console, the 'rows' array is populated as expected from the result of the DB query. However, when the output from the console.log(rows) is printed client side, the 'rows' variable is undefined.
This should be such a simple piece of code, but it's getting the best of me. I have other socket emits that function almost identically to the above code, yet this particular emit is just not having it.
Any ideas?