I want to select data after inserting, so what i want is to check it every second if there is a new data. I create a select query then try to display it using console log. Please help me, I'm a newbie. Here is my code
Controller
var connection = require('../../config/db');
function myQuery(callback) {
this.pushActivity = function(req, res, next) {
var salesman_id = req.query.salesman_id
connection.acquire(function(err, con) {
con.query('SELECT * FROM `activities` where salesman_id="'+salesman_id+'" and kunci="0" and created=NOW()', function(err, data) {
con.release();
if (err) {
return res.json({ status: 400, message: 'Failed', result: [] });
} else {
console.log(data)
// return res.json(data);
}
});
});
};
callback();
}
function wait10sec(){
setTimeout(function(){
myQuery(wait10sec);
}, 10000);
}
myQuery(wait10sec);
module.exports = new myQuery();
Router
var ad =
require('./../../controllers/mobile/activity_after_deal');
module.exports = {
configure: function(app) {
app.route('/api_ad_push_notif').get(ad.pushActivity);
}
};
This is not a good and efficient approach .Instead of using this ,try to use listener on put request which changes the data and after change event,execute the Get query and output the changed data.Use Socket.io Library for such purposes.
you can use socket.io .
by this module you can send live event to server and get response.
for example when send new data, you can select query or send emit to user or show it on console log
You can create worker by adding
setInterval(function(){
//run query and console
}, 1000) and you can set time
Related
Hello I'm stuck in my first callback "selectArticleByTitle(title, callback)", the terminal send "Cannot read property 'id' of undefined". I don't know how to force the first callback to finish this and launch the others.
router.get('/article/:title', function(req, res){
dataBase.selectArticleByTitle(req.params.title, function(db_titleERR, db_titleResults){
console.log(db_titleResults);
dataBase.selectArticle(db_titleResults[0].id, function(db_resultsArticleERR, db_resultsArticle) {
//Get id of the previous article
dataBase.previousArticle(db_titleResults[0].id, function(db_previousIdERR, db_previousId){
//Get id of the next article
dataBase.nextArticle(db_titleResults[0].id, function(db_nextIdERR, db_nextId){
//Get lastArticle
dataBase.lastArticle(function(db_lastArticleERR, db_lastArticle) {
});
});
});
});
});
});
});
exports.selectArticleByTitle = function(title, callback){
connection.query('select * from article where title=?', [title], function(err, row){
if(err)
callback(err, null);
else{
if(row){
callback(null, row);
}
}
});
}
Here the log
console.log(db_titleResults);
[ RowDataPacket {
id: 7,
genre: 'Sciences',
picture: 'xw',
source: 'xswx',
title: 'zzazzaz',
meta: 'azazadsq',
inputDate: 2017-04-15T10:00:00.000Z,
visitor: 0 } ]
[]
Thank you in advance
If you want to stick with the original code then try the below...
The issue is that you are being returned one row. However you are trying to access the result as if there are many rows being returned in an array.
The below should at least get rid of your error. I would recommend to check the length of the results as well. if db_titleResults.length is defined then you know sql returned an array.
Instead of db_titleResults[0].id, you should use db_titleResults.id.
router.get('/article/:title', function(req, res){
dataBase.selectArticleByTitle(req.params.title, function(db_titleERR, db_titleResults){
console.log(db_titleResults);
dataBase.selectArticle(db_titleResults.id, function(db_resultsArticleERR, db_resultsArticle) {
//Get id of the previous article
dataBase.previousArticle(db_titleResults.id, function(db_previousIdERR, db_previousId){
//Get id of the next article
dataBase.nextArticle(db_titleResults.id, function(db_nextIdERR, db_nextId){
//Get lastArticle
dataBase.lastArticle(function(db_lastArticleERR, db_lastArticle) {
});
});
});
});
});
});
});
I am not sure what library you are using to connect to sql but can avoid nested call backs with an approach like below:
const sql = require('mssql')
sql.connect(config, err => {
// ... error checks
const request = new sql.Request()
request.stream = true // You can set streaming differently for each request
request.query('select * from article where title=?', [title])
request.on('row', row => {
// Emitted for each row in a recordset
dataBase.selectArticle(row.id, ...);
dataBase.previousArticle(row.id, ...);
dataBase.lastArticle(row.id, ...);
});
request.on('error', err => {
// May be emitted multiple times
});
});
I'm using This Node.js module nano
Why I Can't Update my Document? I will Want to Make crazy: true and then False again.
This is My Code:
var nano = require('nano')('http://localhost:5984');
// clean up the database we created previously
nano.db.destroy('alice', function() {
// create a new database
nano.db.create('alice', function() {
// specify the database we are going to use
var alice = nano.use('alice');
// and insert a document in it
alice.insert({ crazy: true }, 'rabbit', function(err, body, header) {
if (err) {
console.log('[alice.insert] ', err.message);
return;
}
console.log('you have inserted the rabbit.')
console.log(body);
});
});
});
Nano doesn’t come with an update method by default. That is why we need to define a custom method that would do it for us. Declare the following near the top of your app.js file, right after your database connection code.
test_db.update = function(obj, key, callback){
var db = this;
db.get(key, function (error, existing){
if(!error) obj._rev = existing._rev;
db.insert(obj, key, callback);
});
}
You can then use the update method in your code:
// and update a document in it
alice.update({ crazy: false }, 'rabbit', function(err, body, header) {
if (err) {
console.log('[alice.insert] ', err.message);
return;
}
console.log('you have updated the rabbit.')
console.log(body);
});
});
});
I've set up a node.js server-app that I want to do some parse.com requests.
I basically want it to return the parse-object JSON-representation.
My route:
var blog = require('./models/model');
app.get('/api/article/:permalink', function(req, res) {
res.json(blog.getArticle(req.params.permalink));
});
And my model:
var Parse = require('parse/node').Parse, // load the parse for node package
keys = require('../../config/keys'); // keys config-file for hosted services
Parse.initialize(keys.app, keys.js);
module.exports = {
getArticle: function(permalink) {
"use strict";
var Article = Parse.Object.extend('Article');
var query = new Parse.Query(Article);
query.include('category');
query.include('profile');
query.equalTo('permalink', permalink);
query.find().then(function(results) {
return results;
}, function(error) {
return error;
});
}
};
The thing is, this returns nothing when I call an article with a permalink that I know to exist (example: http://localhost/api/article/testFoo). I don't get any errors either.
My browser console flashes a message for a split second that reads:
Resource interpreted as Document but transferred with MIME type application/json: "http://localhost/api/article/testFoo"
Any suggestions to what I am doing wrong?
You are trying to use the return value of an async function. This can't work, you need to pass a callback (or the res object) to your getArticle function, which will then use it to send the data back.
With a callback:
app.get('/api/article/:permalink', function(req, res) {
blog.getArticle(req.params.permalink, function(data) {res.json(data)});
});
...
getArticle: function(permalink,callback) {
...
query.find().then(function(results) {
callback(results);
}, function(error) {
callback({error: error});
});
{ text: undefined,
done: false,
_id: 529e16025f5222dc36000002,
__v: 0 }
PUT /api/todos/529e16025f5222dc36000002 200 142ms - 68b
I keep getting this error when trying to do an update for my simple CRUD todo list. When I submit the update, the change doesn't appear on screen, although the put says it's a 200. Not sure what steps to take so that I don't get this "undefined" error and so I can have the update show up on screen.
EDIT: Included more code
This is the back-end node code:
app.put('/api/todos/:_id', function(req, res) {
Todo.findById(req.params._id, function(err, todos){
todos.text = req.body.text;
console.log(todos);
todos.save(function() {
if (!err) {
res.send(todos);
} else if (err) {
res.send(err);
}
Todo.find(function(err, todos) {
if (err)
res.send(err);
res.json(todos);
});
});
});
});
This is the Angular front-end code:
$scope.updateTodo = function(id) {
$scope.newItem = prompt("Please enter your new item:", "");
$http.put('/api/todos/' + id, {formData: $scope.newItem}).success(function(data) {
$scope.todos = data;
});
$http.get('/api/todos').success(function(data) {
$scope.todos = data;
});
};
I think it's because of this:
$http.put('/api/todos/' + id, { formData: $scope.newItem} )
^^^^^^^^
You're passing a single formData parameter with the request, yet in your Express code, you use this:
req.body.text
Either try this:
req.body.formData.text
Or don't use the formData parameter at all and pass $scope.newItem directly.
Besides that, your Express code is a bit messy: it might send back multiple responses and it doesn't check for errors on the save (as #PaulGray also pointed out).
I am currently testing how some code stands up against the following scenario:
Node.js application is started and successfully establishes a connection to mongodb
After it has successfully setup a connection, the mongodb server dies and all subsequent requests fail
To do this I have got the following code which makes use of the official driver (found here: https://github.com/mongodb/node-mongodb-native) :
MongoClient.connect('mongodb://localhost:27017/testdb', function(err, db) {
app.get('/test', function(req, res) {
db.collection('users', function (err, collection) {
console.log(err);
if (err) {
// ## POINT 1 ##
// Handle the error
}
else {
collection.find({ 'username': username }, { timeout: true }).toArray(function(err, items) {
console.log(err);
if (err) {
// ## POINT 2 ##
// Handle the error
}
else {
if (items.length > 0) {
// Do some stuff with the document that was found
}
else {
// Handle not finding the document
}
}
});
}
});
});
});
As the mongodb server is no longer running when the request is being handled, I'd made the assumption that at either the points which I have labelled ## POINT 1 ## or ## POINT 2 ##, it would return an error indicating a timeout; this however, isn't the case.
I have tried a number of different settings (including one you can see here that explicitly allows the cursor to timeout), however I cannot seem to enable it in any way. In every configuration I've tried Node.js will simply keep waiting for the find() operation to callback and it never does.
If I start the Node.js application before running mongodb, it catches the error in the connect callback fine, but if the connection dies after that it doesn't seem to handle it in any way.
Is there a setting I am missing or is there no way to detect connections being terminated after they've been established?
Edit: just to be clear, the username variable used in the find method is actually declared in my full code, the code I've put in this post is a cut down version to illustrate the structure and error checking.
UPD:
Based on this post, looks like they've deployed fix that will do the same as what we do here. Not sure if this is already within npm (15.10.13). https://github.com/mongodb/node-mongodb-native/issues/1092#ref-commit-2667d13
After some investigation I've managed to understand what is going on there:
Every time you call any method to deal with database (find, update, insert, etc.) it creates cursor, that has own ID and registers itself to EventEmitter of Db for being called back later. In meantime it registers itself to _notReplied object within same CallBackStore.
But once connection is closed, I couldn't locate anything that would iterate through _notReplied cursors and would trigger them with errors or any logic with timers (it still might be somewhere there). So I've managed to write small work around, that does force triggers cursors with error when DB emits close event:
new mongodb.Db('testdb', new mongodb.Server('localhost', 27017, { }), { safe: true }).open(function (err, db) {
if (!err) {
db.on('close', function() {
if (this._callBackStore) {
for(var key in this._callBackStore._notReplied) {
this._callHandler(key, null, 'Connection Closed!');
}
}
});
// ...
} else {
console.log(err)
}
});
I recommend using first approach instead of MongoClient. Reasons are few: for example when you close connection and then call .find it will properly trigger error in callback, while with MongoClient it won't.
If you are using MongoClient:
MongoClient.connect('mongodb://localhost:27017/testdb', function(err, db) {
if (!err) {
db.on('close', function() {
if (this._callBackStore) {
for(var key in this._callBackStore._notReplied) {
this._callHandler(key, null, 'Connection Closed!');
}
}
});
// ...
} else {
console.log(err);
}
});
What this will do? Once connection is closed, it will iterate through All _notReplied cursors and trigger events for them with error Connection Closed!.
Test case:
items.find({ }).toArray(function(err, data) {
if (!err) {
console.log('Items found successfully');
} else {
console.log(err);
}
});
db.close();
That will force close database connection and trigger close event that you handle earlier and will make sure that cursor will be closed.
UPD:
I've added Issue on GitHub: https://github.com/mongodb/node-mongodb-native/issues/1092 we'll see what they say regarding this.
I had the same problem, and found this page from google.
But your choosed answer didn't resolve the problem and it is as same as you, this._callBackStore can't use
but i tried to wrap the Mongo, and it seems work fine
var MongoClient = require('mongodb').MongoClient;
var mongo = {};
mongo.init = function() {
MongoClient.connect('mongodb://localhost:27017/testdb', function(err, db) {
if (err) {
mongo.DB = '';
} else {
mongo.DB = db;
}
db.on('close', function() {
mongo.DB = '';
});
db.on('reconnect', function() {
mongo.DB = db;
});
}
}
mongo.getdb = function(callback) {
if (mongo.DB) {
callback(null, mongo.DB);
} else {
callback('can not connect to db', null);
}
}
module.exports = mongo;
firstly start server and init() it
and then you can require it and use
mongo.getdb(function(err, db) {
if (err) {
console.log(err);
} else {
db.collection('user').find({'xxx':'xxx'}).toArray(function(err, items) {
console.log(items);
});
}
});
After some further investigation, it seems that you can't specify "offline" timeouts such as in the scenario outlined above. The only timeout that can be specified is one which informs the server to timeout the cursor after 10 minutes of inactivity, however as in the scenario above the connection to the server is down this does not work.
For reference, I found the information here: https://github.com/mongodb/node-mongodb-native/issues/987#issuecomment-18915263 by who I believed to be one of the main contributors to the project.
I'm making api with Hapi and Mongodb (w/o mongoose). Features:
Start responding to API request only if mongo db is available
Stop responding if mongo dies during cycle
Re-start when mongo available again
Keep single connection for all requests
Combining some ideas from other answers and this post https://productbuilder.wordpress.com/2013/09/06/using-a-single-global-db-connection-in-node-js/ my approach is this:
server.js
Utilities.initializeDb(() => {
server.start((err) => {
if (err) throw err;
console.log('Server running at:', server.info.uri);
});
}, () => {
server.stop((err) => {
if (err) throw err;
console.log('Server stopped');
});
});
Utilities.js
"use strict";
const MongoClient = require('mongodb').MongoClient;
const MongoUrl = 'mongodb://localhost:27017/db';
export const Utilities = {
initializeDb: (next, onCrash) => {
const ConnectToDatabase = (params) => {
MongoClient.connect(MongoUrl, (err, db) => {
if (err !== null) {
console.log('#t4y4542te Can not connect to mongo db service. Retry in 2 seconds. Try #' + params.retry);
console.error(err);
setTimeout(() => {
ConnectToDatabase({retry: params.retry + 1});
}, 2000);
} else {
db.on('close', () => {
onCrash();
console.log('#21df24sf db crashed!');
ConnectToDatabase({retry: 0});
});
global.db = global.db || db;
next();
}
});
};
ConnectToDatabase({retry: 0});
}
};
I'm exporting db connection to global space. It feels like not best solution, but I had projects where db connection was passed as param to all modules and that sucked more. Maybe there should be some modular approach where you import db connection where you need it, but in my situation i need it almost everywhere, I would have to write that include statement in most files. This API is pointless w/o connection to db, so I think it might be best solution even if I'm against having something flying magically in global space..