am working on push notifications using mongodb and nodejs.
I can see the newly added notifications (which are addede in Mongodb) in my browser
But, if I updated the record, the value is not updating in the browser
// if no error get reference to colelction named: 'notifications'
db.collection('notifications', function(err, collection){
if(err) {
throw err;
}
// if no error apply a find() and get reference to doc
collection.find().sort({
$natural: -1
}).limit(1).nextObject(function(err, doc) {
// Rewind the cursor, resetting it to point to the start of the query
if(err) {
throw err;
}
// using tailable cursor get reference to our very first doc
var query = {
_id: {
$gt: doc._id
}
};
var options = {
tailable: true,
awaitdata: true,
numberOfRetries: -1
};
var cursor = collection.find(query, options).sort({
$natural: 1
});
// This function will take cursor to next doc from current as soon as 'notifications' database is updated
function next() {
cursor.nextObject(function(err, message) {
if (err) throw err;
console.log(message.message);
mdsok.volatile.emit('notification', message);
next();
});
}
// what you need to do is: call it first time
next();
});
This is what i am doing in my code.
what should I do to update the value in the browser when I update the same in db.
Please help me . Thanks in advance!
My problem was solved upto some extent.
var http = require('http'),
fs = require('fs'),
// NEVER use a Sync function except at start-up!
index = fs.readFileSync('index.html');
// Send index.html to all requests
var app = http.createServer(function(req, res) {
res.writeHead(200, {
'Content-Type': 'text/html'
});
res.end(index);
});
// Socket.io server listens to our app
var io = require('socket.io').listen(app);
var MongoClient = require('mongodb').MongoClient;
function getdata(){
MongoClient.connect("mongodb://127.0.0.1:27017/test", function(err, db) {
var collection = db.collection('my_collection');
var stream = collection.find({
//'_id': new ObjectID('53eb6f2e75fd7ad00d000029')
//_id: ObjectID.createFromHexString("53eb6f2e75fd7ad00d000029")
}).stream();
stream.on("data", function(item) {
io.sockets.emit('db_status', {
status: item.status
});
prev = item.status;
console.log(prev);
});
stream.on("end", function() {
console.log("Done loading data");
});
});
}
// Send current time every 5 secs
setInterval(getdata, 5000);
// Emit welcome message on connection
io.sockets.on('connection', function(socket) {
socket.emit('welcome', {
message: 'Welcome!'
});
socket.on('i am client',function(data){
console.log(data);
});
});
app.listen(3000);
for every 5 secs, i am hitting the db and getting the value and displaying it in the browser.
To get the newly inserted object, we are using .nextObject() in node.js
Is there any way to get the updated object of the db as above in node.js.
Related
I'm beginner in nodeJS and I have some problems to manage asynchronous way of thinking.
I try to save data in my MongoDB Database and retrieve it. I get my data from a websocket service each 1 ms to 5 sec.
When it's each 5 sec there is no problem but each 1ms, when I display my collection content, the data are not already saved.
Here is my code :
// --Websocket event coming every 1 ms--//
while (1) { //Simulate Websocket events coming every 1 ms
dataBookSave(dataArrayfunction, function(log) { //array of data received from websocket event
console.log(log); //Display the callback log from the function dataBookSave
var query = ""; // Empty query in MongoDB to retrieve all data
mongoDb.find(dbName, collectionName, query, function(result) { // get all data from the MongoDB collection.
console.log(results); //Display all data from my MongoDB collection
});
}
}
function dataBookSave(dataArray, callback) {
if (dataArray.length < 1) callback("dataBookSave1"); //test if the array is empty. if yes, generate the callback
for (var i = 0; i < dataArray.length; i++) {
(function(i) { //closure the for loop
var objAdd = JSON.parse('{"data" : ' + dataArray[i] + ' }'); // create the object to add in the collection
mongoDb.insertCollection(dbName, collectionName, objAdd, function() { // insert function in MongoDB
if (i == dataArray.length - 1) // test if the loop is finished.
{
callback("dataBookSave2"); // if yes, generate the callback
}
});
})(i);
}
}
function insertCollection(dbName, collectionName, myObj, callback) {
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/" + dbName;
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbase = db.db(dbName);
dbase.collection(collectionName).insertOne(myObj, function(err, res) {
if (err) throw err;
db.close();
callback();
});
});
}
function find(dbName, collectionName, query, callback) {
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/" + dbName;
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbase = db.db(dbName);
dbase.collection(collectionName).find(query).sort({
_id: -1
}).toArray(function(err, result) {
if (err) throw err;
callback(result);
db.close();
});
});
}
I see when the for loop is executed, the asynchronous process iterate each data of the table and don't wait the insert database function to be executed. When the for loop is done, I read the collection in MongoDB. The problem is that data is still in queue, going to be written in the collection.
How can I resolve that? Give up with the async concept? Use closure? Find a best callback implementation?
You definitely don't want to connect/close the connection to your db every 1ms. Keeping the connection open is in this case recommended.
I haven't run the code bellow but it should work
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/" + dbName;
var mongodb;
var collectionName = "some-collection";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
mongodb = db;
run();
});
function run() {
// --Websocket event coming every 1 ms--//
while (1) { //Simulate Websocket events coming every 1 ms
dataBookSave(dataArrayfunction, function(log) { //array of data received from websocket event
console.log(log); //Display the callback log from the function dataBookSave
find(collectionName, function(result) { // get all datas from the MongoDB collection.
console.log(results); //Display all datas from my MongoDB collection
});
});
}
}
function dataBookSave(dataArray, callback) {
if (dataArray.length < 1) callback("dataBookSave1");
var arr = [];
// push object to arr for bulk insertion
for (var i = 0; i < dataArray.length; i++) {
arr.push({
data: dataArray[i]
});
}
insert(collectionName, arr, function() {
callback("dataBookSave2");
});
}
function insert(col, arr, callback) {
mongodb
.collection(col)
.insertMany(arr, function(err, res) {
if (err) throw err;
callback();
});
}
function find(collectionName, query, callback) {
mongodb
.collection(collectionName)
.find(query)
.sort({ _id: -1 })
.toArray(function(err, result) {
if (err) throw err;
callback(result);
});
}
I am trying to scan the string on redis server by using redis, redis-scanner module but it is not working..
Please find my code as below and written by node js. Any help would appreciated
var conf = require('./config.js'); //config file declarations
var restify = require('restify'); //restify included
var redis = require("redis"); //redis included
var redis_scanner = require('redis-scanner');
var client = redis.createClient(conf.get('redis_cm.redis_port'), conf.get('redis_cm.redis_server'));
client.auth(conf.get('redis_cm.auth'), function (err) {
if (err){
throw err;
}
});
client.on('connect', function() {
console.log('Connected to Redis');
});
client.select(conf.get('redis_cm.database'), function() {
console.log("Redis Database "+conf.get('redis_cm.database')+" selected successfully!..");
});
var options = {
args: ['MATCH','CM:*','COUNT','5'],
onData: function(result, done){
console.log(result);
console.log("result");
client.quit();
process.exit(1);
},
onEnd: function(err){
console.log("error");
}
};
var scanner = new redis_scanner.Scanner(client, 'SCAN', null, options);
You can use the scan command available in redis from version 2.8.0. Check the documentation from http://redis.io/commands/scan.
Sample code:
var cursor = '0';
function scan(){
redisClient.scan(cursor, 'MATCH', 'CM:*', 'COUNT', '5', function(err, reply){
if(err){
throw err;
}
cursor = reply[0];
if(cursor === '0'){
return console.log('Scan Complete');
}else{
// do your processing
// reply[1] is an array of matched keys.
// console.log(reply[1]);
return scan();
}
});
}
scan(); //call scan function
here is my model code to insert some records. On my work pc it works perfectly, but when I'm running it on my home pc with the same OS, collection.insert doesn't running its callback, so I get just long request which ends with time out. There are no errors, mongo db logs say "Connection accepted" 5 times, and after that there are no messages. The same happens when I try to fetch objects from database using find(). Inserting records with mongo shell works great, but with node.js I couldn't accomplish that.
/*
* POST populate locations.
*/
var MongoClient = require('mongodb').MongoClient,
_ = require('underscore'),
env = process.env.NODE_ENV || 'development',
config = require('../config/config')[env]
exports.connect = function(cb) {
MongoClient.connect(config.db, function(err, db) {
if (err) throw err;
cb(db)
});
}
exports.populate = function(data, cb) {
var self = this;
self.connect(function(db) {
var collection = db.collection('locations');
collection.insert(data, function(err, docs) {
collection.ensureIndex({
"loc": "2dsphere"
}, function() {
db.close();
cb();
});
});
});
}
Use
exports.populate = function(data, cb) {
MongoClient.connect(config.db, function(db) {
var collection = db.collection('locations');
collection.insert(data, function(err, docs) {
collection.ensureIndex({
"loc": "2dsphere"
}, function() {
db.close();
cb();
});
});
});
}
I'm having trouble retrieving data from a mongodb collection which I believe has been inserted correctly.
So here is my example code...
var db = require('./database');
module.exports = function (app) {
app.get('/db', function (req, res) {
db.collection('myCollection', function (err, myCollection) {
if (err) {
return console.error(err);
}
var docrow = {
// no id specified, we'll let mongodb handle that
name: 'Mark',
date: '2013/09/11',
description: 'Some text here'
};
console.log('I GET HERE OK');
myCollection.insert(docrow, { safe: true }, function (err, insertedDocument) {
console.log('BUT I DONT GET HERE?');
if (err && err.name === 'MongoError' && err.code === 11000) {
return console.log('This document already exists');
} else if (err) {
return console.log('Something bad happened');
}
myCollection.find({ name: 'Mark' }, function (err, docs) {
docs.each(function (err, doc) {
console.log(doc);
});
});
});
res.end('OK we made it');
});
});
};
...and the database.js file is...
var Db = require('mongodb').Db,
Connection = require('mongodb').Connection,
Server = require('mongodb').Server;
var host = process.env['MONGO_NODE_DRIVER_HOST'] != null ? process.env['MONGO_NODE_DRIVER_HOST'] : 'localhost';
var port = process.env['MONGO_NODE_DRIVER_PORT'] != null ? process.env['MONGO_NODE_DRIVER_PORT'] : Connection.DEFAULT_PORT;
/*
w:1 tells mongo to wait until at least one confirmed write has succeeded before calling any callbacks
*/
var flags = { w: 1 };
var server = new Server(host, port, { auto_reconnect: true, poolSize: 20 });
var db = new Db('TestDBName', server, flags);
module.exports = db;
It looks like I'm able to create a Collection (myCollection) without error, and calling insert on the collection doesn't error either, but also doesn't appear to get any where near inside the callback function for it to trigger either an error or handle a success?
What am I doing wrong here?
Thanks for any help you can give me.
When you connect to mongodb it is asynchronous method, so it will return client handler in callback, and this client handler have to be used onwards instead of handle of that Db object. So change this:
var db = new Db('TestDBName', server, flags);
To this:
new Db('TestDBName', server, flags).open(function(err, client) {
if(err) throw err;
// client - is the guy you are looking for instead of `db` you had
});
As well change:
myCollection.find({ name: 'Mark' }, function (err, docs) {
To:
myCollection.find({ name: 'Mark' }).toArray(function (err, docs) {
It is the only exception with mongo-native where you have to use .toArray instead of direct callback.
I'm trying to return the JSON data in a mongoose document, and then display it using Angular. There's no errors on the page when using this code. The $http.get method in the Angular IndexCtrl never makes it to success, which leads me to believe the problem is how I'm implementing the API get method. Any help rewriting that method to return properly greatly appreciated!
To clarify: what I want is to be able to access the document like a JSON Object so I can display the data to the client.
update: it does produce the error:
GET http://localhost:3000/api/tracks
It takes a while for that error to show in the console
the api method
app.get("/api/tracks", function(req, res) {
return Track.find({}, function (err, tracks) {
if (err) {
res.send(500);
return;
}
return res.json({
tracks: tracks
});
});
});
the mongoose database
var mongoose = require('mongoose');
var uristring =
process.env.MONGOLAB_URI ||
'mongodb://localhost/HelloMongoose';
var mongoOptions = { db: { safe: true }};
var db = mongoose.createConnection(uristring, mongoOptions, function (err, res) {
if (err) {
console.log ('ERROR connecting to: ' + uristring + '. ' + err);
} else {
console.log ('Succeeded connected to: ' + uristring);
}
});
//a Schema for a track
var Schema = new mongoose.Schema({
name: String,
location: String,
description: String
});
var Track = mongoose.model('Track', Schema);
var spot = new Track({name: 'zildjian'});
spot.save(function (err) {
console.log('saved');
if (err) // ...
console.log('meow');
});
The Angular controller
function IndexCtrl($scope, $http) {
$http.get('/api/tracks').
success(function(data, status, headers, config) {
$scope.tracks = data.tracks;
console.log($scope.tracks + "scope tracks data"); //This does not log! it never makes it this far
});
}
The Jade template that displays $scope.tracks
p There are {{tracks.length}} posts
div(ng-repeat='track in tracks')
h3 {{track.name}}
div {{track.description}}
I was not pulling the entries from the model correctly. Here is how I fixed it:
app.get("/api/tracks", function (req, res) {
var track = [];
var Track = mongoose.model('Track', trackSchema);
Track.find({}, function (err, records) {
records.forEach(function (post, i) {
track.push({
id: i,
title: post.title,
text: post.text.substr(0, 50) + '...'
});
});
res.json({
track: track
});
});
};
}